<?php

namespace App\Http\Controllers\Admin;

use AllowDynamicProperties;
use App\Http\Controllers\Controller;
use App\Http\Requests\Menu\MenuBulkDeleteRequest;
use App\Http\Requests\Menu\MenuCreateRequest;
use App\Http\Requests\Menu\MenuItemCreateRequest;
use App\Http\Requests\Menu\MenuUpdateRequest;
use App\Models\BlogCategory;
use App\Models\BlogPost;
use App\Models\KBArticle;
use App\Models\KBCategory;
use App\Models\MenuItem;
use App\Models\Page;
use App\Services\MenuService;
use App\Services\ProductCategoryService;
use App\Services\ProductService;
use Laracasts\Flash\Flash;

#[AllowDynamicProperties]
class AdminMenusController extends Controller
{
    protected array $data;

    public function __construct(MenuService $menuService, ProductCategoryService $productCategoryService, ProductService $productService)
    {
        $this->data['title'] = 'Menus';
        $this->productCategoryService = $productCategoryService;
        $this->productService = $productService;
        $this->menuService = $menuService;
    }

    public function index()
    {
        $this->data['menus'] = $this->menuService->all();

        return view('admin.menus.index', $this->data);
    }

    public function create()
    {
        $this->data['title'] = 'Create Menu';

        return view('admin.menus.create', $this->data);
    }

    public function store(MenuCreateRequest $request)
    {
        $validateData = $request->validated();

        $this->menuService->store($validateData);

        return redirect()->route('ch-admin.menus.index')->with('success', 'Menu created successfully!');
    }

    public function edit($id)
    {
        $this->data['menu'] = $this->menuService->find($id);

        if (!$this->data['menu']) {
            return redirect()->back()->with('error', 'Menu item not found!');
        }

        $this->data['title'] = 'Edit Menu';

        $this->data['menuLocations'] = theme_menu_locations();

        return view('admin.menus.edit', $this->data);
    }

    public function update(MenuUpdateRequest $request, $id)
    {
        $validateData = $request->validated();

        $this->menuService->update($validateData, $id);

        return redirect()->route('ch-admin.menus.index')->with('success', 'Menu updated successfully!');
    }

    public function destroy($id)
    {
        $this->menuService->delete($id);

        return redirect()->back()->with('success', 'Menu deleted successfully.');
    }

    public function bulkDestroy(MenuBulkDeleteRequest $request)
    {
        $validateData = $request->validated();

        try {
            $this->menuService->deleteAll($validateData['menu_ids']);

            Flash::success('Menu deleted successfully.');

            return response()->json(['success' => true]);
        } catch (\Exception $ex) {
            Flash::error('Failed to delete menu: ' . $ex->getMessage());

            return response()->json(['success' => false]);
        }
    }

    public function builder($id)
    {
        $menu = $this->menuService->find($id);

        if(!$menu) {
            return redirect()->route('ch-admin.menu.index')->with('error', 'Menu item not found!');
        }

        $this->data['menu'] = $menu;
        $this->data['title'] = 'Menu Builder';
        $this->data['blogposts'] = BlogPost::all();
        $this->data['productCategories'] = $this->productCategoryService->all();
        $this->data['products'] = $this->productService->all();
        $this->data['blogPostCategories'] = BlogCategory::all();
        $this->data['pages'] = Page::where('is_published', true)->get();
        $this->data['menuItems'] = $this->getNestedMenuItems($menu->id);

        return view('admin.menus.builder', $this->data);
    }

    public function builderStore(MenuItemCreateRequest $request, $id)
    {
        $menu = $this->menuService->find($id);

        if (!$menu) {
            return response()->json([
                'success' => false,
                'message' => 'Menu item not found!'
            ], 404);
        }

        $validatedData = $request->validated();

        MenuItem::where('menu_id', $menu->id)->delete();

        $this->menuService->clearMenuCache($menu->id);

        $createdItems = [];

        $this->storeMenuItems($validatedData['menuItems'], $menu->id);

        return response()->json([
            'success' => true,
            'message' => 'Menu items saved successfully!',
            'created_items' => $createdItems, // Send back the created menu items
        ], 200);
    }

    public function storeMenuItems(array $menuItems, int $menuId, int $parentId = null)
    {
        foreach ($menuItems as $index => $item) {
            // Create the menu item
            $menuItem = MenuItem::create([
                'menu_id' => $menuId,
                'title' => $item['title'],
                'url' => $item['url'] ?? null,
                'parent_id' => $parentId,
                'order' => $index,
                'css_class' => $item['css_class'] ?? null,
            ]);

            // Process children recursively
            if (isset($item['children']) && is_array($item['children']) && !empty($item['children'])) {
                $this->storeMenuItems($item['children'], $menuId, $menuItem->id);
            }
        }
    }

    public function getNestedMenuItems($menuId, $parentId = null)
    {
        return MenuItem::where('menu_id', $menuId)
            ->where('parent_id', $parentId)
            ->orderBy('order')
            ->get()
            ->map(function ($item) use ($menuId) {
                return [
                    'id' => $item->id,
                    'title' => $item->title,
                    'url' => $item->url,
                    'children' => $this->getNestedMenuItems($menuId, $item->id),
                ];
            });
    }
}
