<?php

namespace AleshaCMS\Http\Controllers\Admin;

use AleshaCMS\Http\Controllers\Controller;
use AleshaCMS\Models\CMS\Menu;
use AleshaCMS\Models\CMS\MenuItem;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class MenuController extends Controller
{
    public function index(Request $request)
    {
        $menus = Menu::withCount('allItems')->get();

        if ($request->wantsJson()) {
            return response()->json([
                'data' => $menus->map(fn($m) => [
                    'id' => $m->id,
                    'name' => $m->name,
                    'slug' => $m->slug,
                    'location' => $m->location ?? 'unassigned',
                    'items_count' => $m->all_items_count,
                    'edit_url' => route('admin.menus.edit', $m->id),
                ]),
            ]);
        }

        return view('admin.menus.index', compact('menus'));
    }

    public function create()
    {
        return view('admin.menus.create');
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:100',
            'slug' => 'nullable|string|max:100|unique:menus',
            'location' => 'nullable|string|max:50',
        ]);

        $data['slug'] = $data['slug'] ?? Str::slug($data['name']);
        $menu = Menu::create($data);

        if ($request->wantsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Menu created.',
                'redirect' => route('admin.menus.edit', $menu->id),
            ]);
        }

        return redirect()->route('admin.menus.edit', $menu->id)->with('success', 'Menu created.');
    }

    public function edit(Menu $menu)
    {
        $menu->load(['items.children']);
        return view('admin.menus.edit', compact('menu'));
    }

    public function update(Request $request, Menu $menu)
    {
        if (is_string($request->items)) {
            $request->merge(['items' => json_decode($request->items, true) ?? []]);
        }

        $data = $request->validate([
            'items' => 'required|array',
        ]);

        // Collect all incoming DB ids to know what to delete
        $incomingIds = [];
        $this->collectIds($data['items'], $incomingIds);
        $menu->allItems()->whereNotIn('id', array_filter($incomingIds))->delete();

        foreach ($data['items'] as $sort => $item) {
            $this->saveMenuItem($menu->id, $item, null, $sort);
        }

        if ($request->wantsJson()) {
            return response()->json(['success' => true, 'message' => 'Menu saved.']);
        }

        return back()->with('success', 'Menu saved.');
    }

    protected function collectIds(array $items, array &$ids): void
    {
        foreach ($items as $item) {
            if (!empty($item['id'])) $ids[] = $item['id'];
            $this->collectIds($item['children'] ?? [], $ids);
        }
    }

    protected function saveMenuItem(int $menuId, array $item, ?int $parentId, int $sort = 0): void
    {
        $attrs = [
            'menu_id'      => $menuId,
            'parent_id'    => $parentId,
            'label'        => $item['label'],
            'url'          => $item['url'] ?? '#',
            'type'         => $item['type'] ?? 'custom',
            'reference_id' => $item['reference_id'] ?? null,
            'target'       => $item['target'] ?? '_self',
            'sort_order'   => $sort,
        ];

        if (!empty($item['id']) && is_numeric($item['id'])) {
            $menuItem = MenuItem::find($item['id']);
            if ($menuItem) {
                $menuItem->update($attrs);
            } else {
                $menuItem = MenuItem::create($attrs);
            }
        } else {
            $menuItem = MenuItem::create($attrs);
        }

        foreach ($item['children'] ?? [] as $childSort => $child) {
            $this->saveMenuItem($menuId, $child, $menuItem->id, $childSort);
        }
    }

    public function destroy(Menu $menu)
    {
        $menu->delete();

        if (request()->wantsJson()) {
            return response()->json(['success' => true, 'message' => 'Menu deleted.']);
        }

        return redirect()->route('admin.menus.index')->with('success', 'Menu deleted.');
    }
}
