'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { api } from '@/lib/api';
import { useAuth } from '@/components/auth-context';
import { toast } from 'react-toastify';
import { showConfirmDelete } from '@/lib/confirm';
import { DataTable } from '@/components/data-table/DataTable';
import { DataTableActions } from '@/components/data-table/DataTableActions';
import SearchableSelect from '@/components/SearchableSelect';
import BackToDashboard from '@/components/BackToDashboard';
import { PageLoader } from '@/components/DotLoader';
import { useRequirePermission } from '@/lib/useRequirePermission';

interface MenuRow {
  id: number;
  name: string;
  route: string;
  icon: string;
  parent: number | null;
  sort_order: number;
  permission_code: string;
  is_active: boolean;
}

interface PermItem {
  key: string;
  name: string;
  app_label: string;
}

const EMPTY: Omit<MenuRow, 'id'> = {
  name: '', route: '', icon: '', parent: null,
  sort_order: 0, permission_code: '', is_active: true,
};

// Order rows as a tree: each top-level parent immediately followed by its children.
function treeOrder(rows: MenuRow[]): MenuRow[] {
  const by = (a: MenuRow, b: MenuRow) => a.sort_order - b.sort_order || a.id - b.id;
  const tops = rows.filter((m) => !m.parent).sort(by);
  const out: MenuRow[] = [];
  for (const p of tops) {
    out.push(p);
    rows.filter((m) => m.parent === p.id).sort(by).forEach((c) => out.push(c));
  }
  // append any orphaned children (parent missing) so nothing is lost
  const shown = new Set(out.map((m) => m.id));
  rows.filter((m) => !shown.has(m.id)).forEach((m) => out.push(m));
  return out;
}

export default function AdminMenusPage() {
  useRequirePermission('menus.view_menu');
  const router = useRouter();
  const { user: me } = useAuth();
  const [loading, setLoading] = useState(true);
  const [menus, setMenus] = useState<MenuRow[]>([]);
  const [catalog, setCatalog] = useState<PermItem[]>([]);

  const [showModal, setShowModal] = useState(false);
  const [editId, setEditId] = useState<number | null>(null);
  const [form, setForm] = useState<Omit<MenuRow, 'id'>>(EMPTY);
  const [saving, setSaving] = useState(false);

  // Permission search dropdown
  const [permSearch, setPermSearch] = useState('');
  const [permDropdownOpen, setPermDropdownOpen] = useState(false);
  const permDropdownRef = useRef<HTMLDivElement>(null);
  const permTriggerRef = useRef<HTMLButtonElement>(null);
  const [permDropdownStyle, setPermDropdownStyle] = useState<React.CSSProperties>({});

  const openPermDropdown = () => {
    if (permTriggerRef.current) {
      const rect = permTriggerRef.current.getBoundingClientRect();
      const spaceBelow = window.innerHeight - rect.bottom;
      const spaceAbove = rect.top;
      const dropH = Math.min(340, catalog.length * 52 + 60);
      const goUp = spaceBelow < dropH && spaceAbove > spaceBelow;
      setPermDropdownStyle({
        position: 'fixed',
        left: rect.left,
        width: rect.width,
        ...(goUp
          ? { bottom: window.innerHeight - rect.top + 4 }
          : { top: rect.bottom + 4 }),
        zIndex: 9999,
      });
    }
    setPermDropdownOpen(true);
  };

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (
        permDropdownRef.current && !permDropdownRef.current.contains(e.target as Node) &&
        permTriggerRef.current && !permTriggerRef.current.contains(e.target as Node)
      ) {
        setPermDropdownOpen(false);
      }
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  const loadMenus = useCallback(async () => {
    const res = (await api.get('/menus/admin/menus/?page_size=500')) as any;
    const rows: MenuRow[] = res?.data?.results ?? res?.results ?? res?.data ?? res ?? [];
    setMenus(Array.isArray(rows) ? treeOrder(rows) : []);
  }, []);

  useEffect(() => {
    if (!me) return;
    (async () => {
      try {
        if (me.role === 'ADMIN') {
          const cat = (await api.get('/users/admin/permissions/')) as any;
          setCatalog(cat?.data ?? []);
          await loadMenus();
        }
      } finally {
        setLoading(false);
      }
    })();
  }, [me, loadMenus]);

  const nameById = (id: number | null) =>
    id == null ? '—' : menus.find((m) => m.id === id)?.name ?? `#${id}`;

  const openAdd = () => { setEditId(null); setForm(EMPTY); setPermSearch(''); setShowModal(true); };
  const openEdit = (m: MenuRow) => {
    setEditId(m.id);
    const { id, ...rest } = m;
    setForm(rest);
    setPermSearch('');
    setShowModal(true);
  };

  const save = async () => {
    if (!form.name.trim()) { toast.error('Name is required'); return; }
    setSaving(true);
    try {
      const payload = { ...form, parent: form.parent || null };
      if (editId) await api.put(`/menus/admin/menus/${editId}/`, payload);
      else await api.post('/menus/admin/menus/', payload);
      toast.success(editId ? 'Menu updated' : 'Menu created');
      setShowModal(false);
      await loadMenus();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Could not save menu');
    } finally {
      setSaving(false);
    }
  };

  const remove = async (m: MenuRow) => {
    const result = await showConfirmDelete(`Delete menu "${m.name}"?`);
    if (!result.isConfirmed) return;
    try {
      await api.delete(`/menus/admin/menus/${m.id}/`);
      toast.success('Menu deleted');
      await loadMenus();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Could not delete');
    }
  };

  const columns = [
    {
      accessorKey: 'name',
      header: 'Name',
      size: 260,
      cell: ({ row }: any) => {
        const m: MenuRow = row.original;
        return (
          <span className={`inline-block min-w-[220px] whitespace-nowrap ${m.parent ? 'pl-4 text-slate-600 dark:text-slate-400' : 'font-semibold text-slate-800 dark:text-slate-200'}`}>
            {m.name}
          </span>
        );
      },
    },
    { accessorKey: 'route', header: 'Route', cell: ({ row }: any) => <span className="text-slate-500">{row.original.route || '—'}</span> },
    {
      id: 'parent',
      accessorFn: (m: MenuRow) => nameById(m.parent),
      header: 'Parent',
      cell: ({ row }: any) => <span className="text-slate-500 whitespace-nowrap">{nameById(row.original.parent)}</span>,
    },
    {
      accessorKey: 'permission_code',
      header: 'Permission',
      cell: ({ row }: any) => row.original.permission_code
        ? <code className="text-xs bg-slate-100 dark:bg-slate-800 px-1.5 py-0.5 rounded-none">{row.original.permission_code}</code>
        : <span className="text-slate-400 text-xs">— (parent)</span>,
    },
    { accessorKey: 'sort_order', header: 'Order', cell: ({ row }: any) => <span className="text-slate-500">{row.original.sort_order}</span> },
    {
      id: 'status',
      accessorFn: (m: MenuRow) => (m.is_active ? 'Active' : 'Hidden'),
      header: 'Status',
      cell: ({ row }: any) => row.original.is_active
        ? <span className="text-emerald-600 text-xs font-semibold">Active</span>
        : <span className="text-slate-400 text-xs">Hidden</span>,
    },
    {
      id: 'actions',
      header: 'Actions',
      cell: ({ row }: any) => (
        <DataTableActions onEdit={() => openEdit(row.original)} />
      ),
    },
  ];

  if (loading) return <PageLoader />;

  if (me?.role !== 'ADMIN') {
    return (
      <div className="flex-1 flex flex-col items-center justify-center gap-4">
        <p className="text-slate-500">Only an administrator can manage menus.</p>
        <button onClick={() => router.push('/dashboard')}
          className="bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-semibold py-2.5 px-5 rounded-none">
          Go to Dashboard
        </button>
      </div>
    );
  }

  return (
    <>
        <main className="flex-1 p-6 overflow-x-auto">
          <BackToDashboard />
          <div className="flex items-center justify-between mb-5">
            <div>
              <h1 className="text-xl font-bold text-slate-800 dark:text-slate-100">Menus</h1>
              <p className="text-sm text-slate-500">Sidebar items. Link each to a permission; leave blank for a parent.</p>
            </div>
            <button onClick={openAdd}
              className="bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-semibold py-2.5 px-4 rounded-none flex items-center gap-2">
              <i className="fa-solid fa-plus"></i> Add menu
            </button>
          </div>

          <DataTable
            columns={columns}
            data={menus}
            loading={loading}
            searchPlaceholder="Search menus by name, route, permission..."
            filters={[
              {
                columnId: 'status',
                title: 'Status',
                placeholder: 'All statuses',
                options: [
                  { label: 'Active', value: 'Active' },
                  { label: 'Hidden', value: 'Hidden' },
                ],
              },
            ]}
            emptyStateTitle="No Menus Found"
            emptyStateDescription="Add a menu, or adjust your search and filters."
          />
        </main>

      {showModal && (
        <div className="fixed inset-0 z-[100] bg-slate-950/50 flex items-center justify-center p-4"
          onClick={() => !saving && setShowModal(false)}>
          <div className="bg-white dark:bg-slate-900 rounded-none w-full max-w-md p-6 space-y-4 relative"
            onClick={(e) => e.stopPropagation()}>
            <h2 className="text-lg font-bold text-slate-800 dark:text-slate-100">
              {editId ? 'Edit menu' : 'Add menu'}
            </h2>

            <div className="space-y-3">
              <label className="block">
                <span className="text-xs font-semibold text-slate-500">Name</span>
                <input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })}
                  className="mt-1 w-full border border-slate-300 dark:border-slate-700 dark:bg-slate-800 rounded-none px-3 py-2 text-sm" />
              </label>

              <label className="block">
                <span className="text-xs font-semibold text-slate-500">Route</span>
                <input value={form.route} placeholder="/admin/users" onChange={(e) => setForm({ ...form, route: e.target.value })}
                  className="mt-1 w-full border border-slate-300 dark:border-slate-700 dark:bg-slate-800 rounded-none px-3 py-2 text-sm" />
              </label>

              <label className="block">
                <span className="text-xs font-semibold text-slate-500">Icon (Font Awesome class)</span>
                <input value={form.icon} placeholder="fa-solid fa-user-plus" onChange={(e) => setForm({ ...form, icon: e.target.value })}
                  className="mt-1 w-full border border-slate-300 dark:border-slate-700 dark:bg-slate-800 rounded-none px-3 py-2 text-sm" />
              </label>

              <div className="grid grid-cols-2 gap-3">
                <label className="block">
                  <span className="text-xs font-semibold text-slate-500">Parent</span>
                  <SearchableSelect
                    value={form.parent ?? ''}
                    onChange={(val) => setForm({ ...form, parent: val ? Number(val) : null })}
                    placeholder="— none (top level)"
                    options={menus.filter((m) => m.id !== editId && !m.parent).map((m) => ({ value: m.id, label: m.name }))}
                    className="mt-1"
                  />
                </label>
                <label className="block">
                  <span className="text-xs font-semibold text-slate-500">Sort order</span>
                  <input type="number" value={form.sort_order} onChange={(e) => setForm({ ...form, sort_order: Number(e.target.value) })}
                    className="mt-1 w-full border border-slate-300 dark:border-slate-700 dark:bg-slate-800 rounded-none px-3 py-2 text-sm" />
                </label>
              </div>

              <div className="block">
                <span className="text-xs font-semibold text-slate-500">Permission (blank = always shown)</span>
                {/* Trigger button showing current selection */}
                <button
                  ref={permTriggerRef}
                  type="button"
                  onClick={() => permDropdownOpen ? setPermDropdownOpen(false) : openPermDropdown()}
                  className="mt-1 w-full border border-slate-300 dark:border-slate-700 dark:bg-slate-800 rounded-none px-3 py-2 text-sm text-left flex items-center justify-between gap-2 bg-white dark:bg-slate-800 hover:border-indigo-400 transition"
                >
                  <span className={form.permission_code ? 'text-slate-800 dark:text-slate-100 truncate' : 'text-slate-400'}>
                    {form.permission_code
                      ? form.permission_code
                      : '— none (parent / always visible)'}
                  </span>
                  <i className={`fa-solid fa-chevron-down text-slate-400 text-xs shrink-0 transition-transform ${permDropdownOpen ? 'rotate-180' : ''}`} />
                </button>

                {/* Centered permission picker panel */}
                {permDropdownOpen && (
                  <div
                    className="fixed inset-0 z-[9999] flex items-center justify-center p-6 bg-slate-950/40 backdrop-blur-sm"
                    onClick={() => { setPermDropdownOpen(false); setPermSearch(''); }}
                  >
                    <div
                      ref={permDropdownRef}
                      className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-none shadow-2xl w-full max-w-lg flex flex-col overflow-hidden"
                      style={{ maxHeight: '70vh' }}
                      onClick={(e) => e.stopPropagation()}
                    >
                      {/* Header */}
                      <div className="px-5 py-4 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between shrink-0">
                        <div>
                          <h3 className="text-sm font-bold text-slate-800 dark:text-slate-100">Select Permission</h3>
                          <p className="text-xs text-slate-400 mt-0.5">
                            {permSearch
                              ? `${catalog.filter(p => p.key.toLowerCase().includes(permSearch.toLowerCase()) || p.name.toLowerCase().includes(permSearch.toLowerCase())).length} results`
                              : `${catalog.length} permissions available`}
                          </p>
                        </div>
                        <button
                          onClick={() => { setPermDropdownOpen(false); setPermSearch(''); }}
                          className="text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 transition cursor-pointer"
                        >
                          <i className="fa-solid fa-xmark text-lg" />
                        </button>
                      </div>

                      {/* Search bar */}
                      <div className="px-4 py-3 border-b border-slate-100 dark:border-slate-800 shrink-0">
                        <div className="flex items-center gap-2 bg-slate-50 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 focus-within:border-indigo-500 rounded-none px-4 py-2.5 transition">
                          <i className="fa-solid fa-magnifying-glass text-slate-400 text-sm" />
                          <input
                            autoFocus
                            type="text"
                            value={permSearch}
                            onChange={(e) => setPermSearch(e.target.value)}
                            placeholder="Search by permission key or description…"
                            className="flex-1 text-sm bg-transparent outline-none text-slate-800 dark:text-slate-100 placeholder-slate-400"
                          />
                          {permSearch && (
                            <button onClick={() => setPermSearch('')} className="text-slate-400 hover:text-slate-600 cursor-pointer">
                              <i className="fa-solid fa-xmark text-xs" />
                            </button>
                          )}
                        </div>
                      </div>

                      {/* Options list */}
                      <div className="overflow-y-auto flex-1">
                        {/* None option */}
                        {!permSearch && (
                          <button
                            type="button"
                            onClick={() => { setForm({ ...form, permission_code: '' }); setPermDropdownOpen(false); setPermSearch(''); }}
                            className={`w-full text-left px-5 py-3 text-sm flex items-center gap-3 hover:bg-slate-50 dark:hover:bg-slate-800 transition border-b border-slate-100 dark:border-slate-800/60 ${form.permission_code === '' ? 'bg-indigo-50 dark:bg-indigo-950/40 text-indigo-600 dark:text-indigo-400 font-semibold' : 'text-slate-500'}`}
                          >
                            <i className={`fa-solid fa-ban text-xs ${form.permission_code === '' ? 'text-indigo-500' : 'text-slate-300'}`} />
                            — none (parent / always visible)
                          </button>
                        )}

                        {/* Filtered permissions */}
                        {catalog
                          .filter((p) => {
                            const q = permSearch.toLowerCase();
                            return !q || p.key.toLowerCase().includes(q) || p.name.toLowerCase().includes(q);
                          })
                          .map((p) => (
                            <button
                              key={p.key}
                              type="button"
                              onClick={() => { setForm({ ...form, permission_code: p.key }); setPermDropdownOpen(false); setPermSearch(''); }}
                              className={`w-full text-left px-5 py-3 hover:bg-slate-50 dark:hover:bg-slate-800 transition flex items-center gap-3 border-b border-slate-50 dark:border-slate-800/40 ${form.permission_code === p.key ? 'bg-indigo-50 dark:bg-indigo-950/40' : ''}`}
                            >
                              <i className={`fa-solid fa-key text-xs shrink-0 ${form.permission_code === p.key ? 'text-indigo-500' : 'text-slate-300'}`} />
                              <div className="min-w-0">
                                <p className={`font-mono text-xs font-semibold truncate ${form.permission_code === p.key ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-700 dark:text-slate-200'}`}>
                                  {p.key}
                                </p>
                                <p className="text-slate-400 dark:text-slate-500 text-[11px] mt-0.5">{p.name}</p>
                              </div>
                              {form.permission_code === p.key && (
                                <i className="fa-solid fa-circle-check text-indigo-500 text-sm ml-auto shrink-0" />
                              )}
                            </button>
                          ))}

                        {/* Empty state */}
                        {permSearch && catalog.filter((p) => {
                          const q = permSearch.toLowerCase();
                          return p.key.toLowerCase().includes(q) || p.name.toLowerCase().includes(q);
                        }).length === 0 && (
                          <div className="flex flex-col items-center justify-center py-12 gap-2 text-slate-400">
                            <i className="fa-solid fa-magnifying-glass text-2xl" />
                            <p className="text-sm">No permissions match &ldquo;{permSearch}&rdquo;</p>
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>

              <label className="flex items-center gap-2">
                <input type="checkbox" checked={form.is_active} onChange={(e) => setForm({ ...form, is_active: e.target.checked })} />
                <span className="text-sm text-slate-600 dark:text-slate-300">Active</span>
              </label>
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <button onClick={() => setShowModal(false)} disabled={saving}
                className="px-4 py-2 rounded-none text-sm border border-slate-300 dark:border-slate-700 text-slate-600 dark:text-slate-300">
                Cancel
              </button>
              <button onClick={save} disabled={saving}
                className="px-4 py-2 rounded-none text-sm font-semibold bg-indigo-600 hover:bg-indigo-500 text-white disabled:opacity-50">
                {saving ? 'Saving…' : 'Save'}
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}
