import { createResource, createSignal, createMemo, Show, For } from 'solid-js';
import { Plus, Pencil, Archive, RotateCcw, Trash2, ChevronLeft, ChevronRight } from 'lucide-solid';
import AdminShell from '~/components/AdminShell';

const API = '/api/gateway';

type Department = {
  id: string;
  departmentId?: string;
  name?: string;
  departmentName?: string;
  description?: string;
  createdBy?: string;
  updatedBy?: string;
  is_archived?: boolean;
  status?: string | number;
  createdAt?: string;
  created_at?: string;
  updatedAt?: string;
};

type ViewMode = 'list' | 'create' | 'update';

async function loadDepartments(params: { page: number; limit: number; status: string }): Promise<{ items: Department[]; total: number }> {
  try {
    const res = await fetch(`${API}/api/admin/departments?page=${params.page}&limit=${params.limit}&status=${params.status}`);
    if (!res.ok) throw new Error('Failed to load');
    const data = await res.json();
    const items = Array.isArray(data) ? data : (data.departments ?? []);
    const total = data.total ?? items.length;
    return { items, total };
  } catch {
    return { items: [], total: 0 };
  }
}

function isArchived(item: Department): boolean {
  if (item.is_archived !== undefined) return item.is_archived;
  if (item.status !== undefined) {
    const s = String(item.status).toUpperCase();
    return s === 'ARCHIVED' || s === '2';
  }
  return false;
}

function deptLabel(item: Department): string {
  return item.departmentName || item.name || '—';
}

function fmtDate(val?: string): string {
  if (!val) return '—';
  try { return new Date(val).toLocaleDateString(); } catch { return val; }
}

export default function DepartmentPage() {
  const [view, setView] = createSignal<ViewMode>('list');
  const [statusFilter, setStatusFilter] = createSignal<'active' | 'archived'>('active');
  const [page, setPage] = createSignal(1);
  const limit = 10;

  const fetchParams = createMemo(() => ({
    page: page(),
    limit,
    status: statusFilter() === 'archived' ? '2' : '1',
  }));

  const [data, { refetch }] = createResource(fetchParams, loadDepartments);

  // form state
  const [createName, setCreateName] = createSignal('');
  const [createDesc, setCreateDesc] = createSignal('');
  const [creating, setCreating] = createSignal(false);
  const [createError, setCreateError] = createSignal('');

  // inline edit
  const [editingId, setEditingId] = createSignal('');
  const [editName, setEditName] = createSignal('');
  const [editDesc, setEditDesc] = createSignal('');
  const [saving, setSaving] = createSignal(false);
  const [editError, setEditError] = createSignal('');

  const [busy, setBusy] = createSignal('');
  const [actionError, setActionError] = createSignal('');

  const items = () => data()?.items ?? [];
  const total = () => data()?.total ?? 0;
  const totalPages = () => Math.ceil(total() / limit);

  const filtered = createMemo(() => {
    const all = items();
    return statusFilter() === 'archived'
      ? all.filter((d) => isArchived(d))
      : all.filter((d) => !isArchived(d));
  });

  const handleCreate = async (e: Event) => {
    e.preventDefault();
    if (!createName().trim()) return;
    setCreating(true);
    setCreateError('');
    try {
      const res = await fetch(`${API}/api/admin/departments`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: createName().trim(), description: createDesc().trim() }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error((err as any).message || 'Failed to create');
      }
      setCreateName(''); setCreateDesc('');
      setView('list'); setStatusFilter('active'); setPage(1);
      refetch();
    } catch (err: any) {
      setCreateError(err.message || 'Failed to create department');
    } finally {
      setCreating(false);
    }
  };

  const startEdit = (item: Department) => {
    setEditingId(item.id); setEditName(deptLabel(item)); setEditDesc(item.description ?? ''); setEditError('');
  };
  const cancelEdit = () => { setEditingId(''); setEditError(''); };

  const handleUpdate = async (id: string) => {
    if (!editName().trim()) return;
    setSaving(true); setEditError('');
    try {
      const res = await fetch(`${API}/api/admin/departments/${id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: editName().trim(), description: editDesc().trim() }),
      });
      if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error((err as any).message || 'Failed to update'); }
      setEditingId(''); refetch();
    } catch (err: any) { setEditError(err.message || 'Failed to update department'); }
    finally { setSaving(false); }
  };

  const handleArchive = async (id: string) => {
    setBusy(id); setActionError('');
    try {
      const res = await fetch(`${API}/api/admin/departments/${id}`, {
        method: 'PATCH', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_archived: true }),
      });
      if (!res.ok) throw new Error('Failed to archive');
      refetch();
    } catch (err: any) { setActionError(err.message || 'Failed to archive department'); }
    finally { setBusy(''); }
  };

  const handleRestore = async (id: string) => {
    setBusy(id); setActionError('');
    try {
      const res = await fetch(`${API}/api/admin/departments/${id}`, {
        method: 'PATCH', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_archived: false }),
      });
      if (!res.ok) throw new Error('Failed to restore');
      refetch();
    } catch (err: any) { setActionError(err.message || 'Failed to restore department'); }
    finally { setBusy(''); }
  };

  const handleDelete = async (id: string, name: string) => {
    if (!confirm(`Delete department "${name}"?`)) return;
    setBusy(id); setActionError('');
    try {
      const res = await fetch(`${API}/api/admin/departments/${id}`, { method: 'DELETE' });
      if (!res.ok) throw new Error('Failed to delete');
      refetch();
    } catch (err: any) { setActionError(err.message || 'Failed to delete department'); }
    finally { setBusy(''); }
  };

  const switchTab = (t: 'active' | 'archived') => {
    setView('list'); setStatusFilter(t); setPage(1); setEditingId('');
  };

  return (
    <AdminShell>
      <div class="flex flex-col -mx-6 -mt-6 min-h-full">

        {/* ── Page header ── */}
        <div class="bg-white border-b border-gray-200 px-6 py-4">
          <h1 class="text-xl font-semibold text-gray-900">Departments</h1>
          <p class="text-sm text-gray-500 mt-0.5">Manage organization structure and units.</p>
        </div>

        {/* ── Tab + action bar ── */}
        <div class="bg-white border-b border-gray-200 px-6 flex items-center justify-between sticky top-0 z-10">
          <div class="flex gap-8">
            <For each={(['active', 'archived'] as const)}>
              {(t) => (
                <button
                  onClick={() => switchTab(t)}
                  class={`py-3 border-b-2 text-sm font-medium capitalize transition-colors ${
                    view() === 'list' && statusFilter() === t
                      ? 'border-orange-500 text-orange-600'
                      : 'border-transparent text-gray-500 hover:text-gray-700'
                  }`}
                >
                  {t} Departments
                </button>
              )}
            </For>
            <Show when={view() === 'create'}>
              <button class="py-3 border-b-2 border-orange-500 text-orange-600 text-sm font-medium">
                Create Department
              </button>
            </Show>
            <Show when={view() === 'update'}>
              <button class="py-3 border-b-2 border-orange-500 text-orange-600 text-sm font-medium">
                Update Department
              </button>
            </Show>
          </div>
          <Show when={view() === 'list'}>
            <button
              onClick={() => { setView('create'); setCreateError(''); setCreateName(''); setCreateDesc(''); }}
              class="btn-primary"
            >
              <Plus size={16} />
              Add Department
            </button>
          </Show>
        </div>

        {/* ── Content ── */}
        <div class="flex-1">

          {/* Create form */}
          <Show when={view() === 'create'}>
            <div class="bg-white border-b border-gray-200 px-6 py-6">
              <form onSubmit={handleCreate} class="grid grid-cols-1 gap-6 md:grid-cols-2 max-w-4xl">
                <div>
                  <label class="mb-1.5 block text-sm font-medium text-gray-700">Department Name *</label>
                  <input
                    type="text" required
                    placeholder="e.g. Engineering"
                    value={createName()}
                    onInput={(e) => setCreateName(e.currentTarget.value)}
                    class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]"
                  />
                </div>
                <div>
                  <label class="mb-1.5 block text-sm font-medium text-gray-700">Description</label>
                  <input
                    type="text"
                    placeholder="Optional description"
                    value={createDesc()}
                    onInput={(e) => setCreateDesc(e.currentTarget.value)}
                    class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]"
                  />
                </div>
                <Show when={createError()}>
                  <p class="md:col-span-2 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">{createError()}</p>
                </Show>
                <div class="md:col-span-2 flex justify-end gap-3 pt-2 border-t border-gray-100">
                  <button type="button" onClick={() => setView('list')} class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors">
                    Cancel
                  </button>
                  <button type="submit" disabled={creating()} class="btn-primary">
                    {creating() ? 'Saving…' : 'Save'}
                  </button>
                </div>
              </form>
            </div>
          </Show>

          {/* List view */}
          <Show when={view() === 'list'}>
            <div class="p-6">
              <Show when={actionError()}>
                <div class="mb-4 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">{actionError()}</div>
              </Show>

              <div class="table-card">
                <div class="overflow-x-auto">
                  <table class="data-table w-full text-sm">
                    <thead>
                      <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Description</th>
                        <th>Created By</th>
                        <th>Created</th>
                        <th>Last Updated By</th>
                        <th>Last Updated At</th>
                        <th class="text-right">Actions</th>
                      </tr>
                    </thead>
                    <tbody>
                      <Show when={data.loading}>
                        <tr><td colspan="8" class="py-10 text-center text-sm text-slate-400">Loading…</td></tr>
                      </Show>
                      <Show when={!data.loading && data.error}>
                        <tr><td colspan="8" class="py-10 text-center text-sm text-red-500">Failed to load. Is the backend running?</td></tr>
                      </Show>
                      <Show when={!data.loading && !data.error && filtered().length === 0}>
                        <tr><td colspan="8" class="py-10 text-center text-sm text-slate-400">No departments found.</td></tr>
                      </Show>
                      <For each={filtered()}>
                        {(item) => (
                          <>
                            <tr class="group hover:bg-slate-50">
                              <td class="font-mono text-xs text-slate-500">{item.departmentId || item.id.slice(0, 8)}</td>
                              <td class="font-semibold text-slate-900">{deptLabel(item)}</td>
                              <td class="text-slate-500">{item.description || '—'}</td>
                              <td class="text-blue-600 hover:underline"><a href={`mailto:${item.createdBy}`}>{item.createdBy || '—'}</a></td>
                              <td class="text-slate-500">{fmtDate(item.createdAt || item.created_at)}</td>
                              <td class="text-blue-600 hover:underline"><a href={`mailto:${item.updatedBy || item.createdBy}`}>{item.updatedBy || item.createdBy || '—'}</a></td>
                              <td class="text-slate-500">{fmtDate(item.updatedAt)}</td>
                              <td>
                                <div class="flex items-center justify-end gap-1.5">
                                  <Show when={!isArchived(item)}>
                                    <button
                                      title="Edit"
                                      onClick={() => startEdit(item)}
                                      class="action-btn flex items-center justify-center hover:bg-gray-50 transition-colors"
                                    >
                                      <Pencil size={14} class="text-gray-600" />
                                    </button>
                                    <button
                                      title="Archive"
                                      disabled={busy() === item.id}
                                      onClick={() => handleArchive(item.id)}
                                      class="action-btn flex items-center justify-center hover:bg-gray-50 transition-colors"
                                    >
                                      <Archive size={14} class="text-gray-600" />
                                    </button>
                                  </Show>
                                  <Show when={isArchived(item)}>
                                    <button
                                      title="Restore"
                                      disabled={busy() === item.id}
                                      onClick={() => handleRestore(item.id)}
                                      class="action-btn flex items-center justify-center hover:bg-gray-50 transition-colors"
                                    >
                                      <RotateCcw size={14} class="text-green-600" />
                                    </button>
                                  </Show>
                                  <button
                                    title="Delete"
                                    disabled={busy() === item.id}
                                    onClick={() => handleDelete(item.id, deptLabel(item))}
                                    class="action-btn flex items-center justify-center border-red-100 bg-red-50 hover:bg-red-100 transition-colors"
                                  >
                                    <Trash2 size={14} class="text-red-600" />
                                  </button>
                                </div>
                              </td>
                            </tr>
                            {/* Inline edit row */}
                            <Show when={editingId() === item.id}>
                              <tr>
                                <td colspan="8" class="bg-slate-50 px-6 py-4">
                                  <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 max-w-2xl">
                                    <div>
                                      <label class="mb-1 block text-xs font-medium text-gray-700">Name *</label>
                                      <input type="text" required value={editName()} onInput={(e) => setEditName(e.currentTarget.value)}
                                        class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" />
                                    </div>
                                    <div>
                                      <label class="mb-1 block text-xs font-medium text-gray-700">Description</label>
                                      <input type="text" value={editDesc()} onInput={(e) => setEditDesc(e.currentTarget.value)}
                                        class="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm outline-none focus:border-[#0a1d37] focus:ring-1 focus:ring-[#0a1d37]" />
                                    </div>
                                  </div>
                                  <Show when={editError()}>
                                    <p class="mt-3 rounded-lg border border-red-200 bg-red-50 px-4 py-2 text-sm text-red-700">{editError()}</p>
                                  </Show>
                                  <div class="mt-3 flex gap-2">
                                    <button type="button" onClick={cancelEdit} class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors">Cancel</button>
                                    <button type="button" disabled={saving()} onClick={() => handleUpdate(item.id)}
                                      class="btn-primary disabled:opacity-60">
                                      {saving() ? 'Saving…' : 'Save'}
                                    </button>
                                  </div>
                                </td>
                              </tr>
                            </Show>
                          </>
                        )}
                      </For>
                    </tbody>
                  </table>
                </div>
              </div>

              {/* Pagination */}
              <Show when={totalPages() > 1}>
                <div class="mt-4 flex items-center justify-between border-t border-gray-200 pt-4">
                  <span class="text-sm text-gray-500">Page {page()} of {totalPages()}</span>
                  <div class="flex gap-2">
                    <button
                      disabled={page() === 1}
                      onClick={() => setPage((p) => p - 1)}
                      class="rounded-lg border border-gray-200 p-2 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40 transition-colors"
                    >
                      <ChevronLeft size={16} />
                    </button>
                    <button
                      disabled={page() >= totalPages()}
                      onClick={() => setPage((p) => p + 1)}
                      class="rounded-lg border border-gray-200 p-2 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40 transition-colors"
                    >
                      <ChevronRight size={16} />
                    </button>
                  </div>
                </div>
              </Show>
            </div>
          </Show>
        </div>
      </div>
    </AdminShell>
  );
}
