<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\Menu;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class MenuController extends Controller
{
    /**
     * Display a listing of the menus.
     */
    public function index(): Response
    {
        $menus = Menu::with(['children'])
            ->whereNull('parent_id')
            ->orderBy('sort_order', 'asc')
            ->get();

        $parentOptions = Menu::whereNull('parent_id')
            ->select('id', 'title')
            ->get();

        $roles = Role::select('id', 'name')->get();
        $permissions = Permission::select('id', 'name')->get();

        // Get distinct group names from DB (only groups that actually have menu items)
        $groups = Menu::distinct()->whereNotNull('group_name')->pluck('group_name')->toArray();

        return Inertia::render('Menus/Index', [
            'menus' => $menus,
            'parentOptions' => $parentOptions,
            'roles' => $roles,
            'permissions' => $permissions,
            'groups' => $groups,
        ]);
    }

    /**
     * Store a newly created menu in storage.
     */
    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'href' => ['required', 'string', 'max:255'],
            'group_name' => ['required', 'string', 'max:255'],
            'icon' => ['nullable', 'string', 'max:255'],
            'roles' => ['nullable', 'array'],
            'roles.*' => ['string', 'exists:roles,name'],
            'permissions' => ['nullable', 'array'],
            'permissions.*' => ['string', 'exists:permissions,name'],
            'sort_order' => ['required', 'integer'],
            'parent_id' => ['nullable', 'integer', 'exists:menus,id'],
        ]);

        $menu = Menu::create([
            'title' => $request->title,
            'href' => $request->href,
            'group_name' => $request->group_name,
            'icon' => $request->icon,
            'roles' => $request->roles,
            'permissions' => $request->permissions,
            'sort_order' => (int) $request->sort_order,
            'parent_id' => $request->parent_id ? (int) $request->parent_id : null,
        ]);

        // Audit Logging
        activity()
            ->performedOn($menu)
            ->causedBy($request->user())
            ->log("Created menu item: {$menu->title} ({$menu->href})");

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

    /**
     * Update the specified menu in storage.
     */
    public function update(Request $request, Menu $menu): RedirectResponse
    {
        $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'href' => ['required', 'string', 'max:255'],
            'group_name' => ['required', 'string', 'max:255'],
            'icon' => ['nullable', 'string', 'max:255'],
            'roles' => ['nullable', 'array'],
            'roles.*' => ['string', 'exists:roles,name'],
            'permissions' => ['nullable', 'array'],
            'permissions.*' => ['string', 'exists:permissions,name'],
            'sort_order' => ['required', 'integer'],
            'parent_id' => [
                'nullable', 
                'integer', 
                'exists:menus,id',
                function ($attribute, $value, $fail) use ($menu) {
                    if ((int)$value === $menu->id) {
                        $fail('A menu item cannot be its own parent.');
                    }
                }
            ],
        ]);

        $menu->update([
            'title' => $request->title,
            'href' => $request->href,
            'group_name' => $request->group_name,
            'icon' => $request->icon,
            'roles' => $request->roles,
            'permissions' => $request->permissions,
            'sort_order' => (int) $request->sort_order,
            'parent_id' => $request->parent_id ? (int) $request->parent_id : null,
        ]);

        // Audit Logging
        activity()
            ->performedOn($menu)
            ->causedBy($request->user())
            ->log("Updated menu item: {$menu->title} ({$menu->href})");

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

    /**
     * Remove the specified menu from storage.
     */
    public function destroy(Request $request, Menu $menu): RedirectResponse
    {
        $menuTitle = $menu->title;
        $menuHref = $menu->href;

        // Audit Logging BEFORE deleting
        activity()
            ->performedOn($menu)
            ->causedBy($request->user())
            ->log("Deleted menu item: {$menuTitle} ({$menuHref})");

        $menu->delete();

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

    /**
     * Bulk rename all menu items in a group.
     */
    public function renameGroup(Request $request): RedirectResponse
    {
        $request->validate([
            'old_name' => ['required', 'string', 'max:255'],
            'new_name' => ['required', 'string', 'max:255'],
        ]);

        Menu::where('group_name', $request->old_name)->update([
            'group_name' => $request->new_name,
        ]);

        // Audit Logging
        activity()
            ->causedBy($request->user())
            ->log("Renamed menu group: {$request->old_name} to {$request->new_name}");

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

    /**
     * Delete all menu items in a group.
     */
    public function deleteGroup(Request $request): RedirectResponse
    {
        $request->validate([
            'group_name' => ['required', 'string', 'max:255'],
        ]);

        Menu::where('group_name', $request->group_name)->delete();

        // Audit Logging
        activity()
            ->causedBy($request->user())
            ->log("Deleted menu group and all its items: {$request->group_name}");

        return redirect()->back()->with('success', 'Menu group and all its items deleted successfully.');
    }
}
