"use client";

import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { AppShell } from "@/components/app/AppShell";
import { PageHeader } from "@/components/layout/PageHeader";
import { DataTable, DataTableEmpty } from "@/components/layout/DataTable";
import { Pagination } from "@/components/layout/Pagination";
import { AdvancedSearchToggle } from "@/components/layout/AdvancedSearchToggle";
import { ActionMenu } from "@/components/layout/ActionMenu";
import { ListExportActions } from "@/components/export/ListExportActions";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { ConfirmDialog } from "@/components/ui/ConfirmDialog";
import { Field, Input, Select } from "@/components/ui/Field";
import {
  ApiError,
  Paginated,
  apiDelete,
  apiGet,
  apiPost,
} from "@/lib/api";
import { startStaffImpersonation } from "@/lib/impersonation";
import {
  getActiveBranchId,
} from "@/lib/session-context";
import { hasPermission } from "@/lib/permissions";
import type { BranchItem } from "@/lib/types";

interface RoleAssignment {
  role_name: string;
  role_label: string;
}

interface StaffRow {
  id: number;
  name: string;
  first_name?: string;
  last_name?: string;
  email: string;
  national_code?: string;
  personnel_code?: string;
  mobile?: string;
  initial_password?: string;
  employment_type?: string;
  employment_type_label?: string;
  is_active: boolean;
  roles?: string[];
  role_labels: string[];
  role_assignments?: RoleAssignment[];
}

interface RoleOption {
  id: number;
  name: string;
  label_fa: string;
}

const emptyFilters = {
  branch_id: "",
  name: "",
  national_code: "",
  personnel_code: "",
  mobile: "",
  role: "",
  employment_type: "",
  is_active: "",
};

function uniqueStaffRoles(u: StaffRow): RoleAssignment[] {
  if (u.role_assignments?.length) {
    const seen = new Set<string>();
    return u.role_assignments.filter((item) => {
      if (!item.role_name || seen.has(item.role_name)) return false;
      seen.add(item.role_name);
      return true;
    });
  }
  const names = u.roles ?? [];
  return (u.role_labels ?? []).map((label, index) => ({
    role_name: names[index] ?? "",
    role_label: label,
  }));
}

function readFiltersFromSearch(search: URLSearchParams) {
  return {
    ...emptyFilters,
    branch_id: search.get("branch_id") ?? String(getActiveBranchId() ?? ""),
    name: search.get("name") ?? "",
    national_code: search.get("national_code") ?? "",
    personnel_code: search.get("personnel_code") ?? "",
    mobile: search.get("mobile") ?? "",
    role: search.get("role") ?? "",
    employment_type: search.get("employment_type") ?? "",
    is_active: search.get("is_active") ?? "",
  };
}

export default function StaffPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [rows, setRows] = useState<StaffRow[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [lastPage, setLastPage] = useState(1);
  const [error, setError] = useState<string | null>(null);
  const [filters, setFilters] = useState(() => readFiltersFromSearch(searchParams));
  const [showSearch, setShowSearch] = useState(() => Boolean(searchParams.get("role")));
  const [branches, setBranches] = useState<BranchItem[]>([]);
  const [roleOptions, setRoleOptions] = useState<RoleOption[]>([]);
  const [deleteId, setDeleteId] = useState<number | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [refresh, setRefresh] = useState(0);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const next = readFiltersFromSearch(searchParams);
    setFilters(next);
    if (next.role) setShowSearch(true);
  }, [searchParams]);

  useEffect(() => {
    apiGet<BranchItem[]>("/branches")
      .then(setBranches)
      .catch(() => setBranches([]));
    apiGet<RoleOption[]>("/roles")
      .then(setRoleOptions)
      .catch(() => setRoleOptions([]));
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams();
      params.set("page", String(page));
      params.set("per_page", "20");
      Object.entries(filters).forEach(([k, v]) => {
        if (v) params.set(k, v);
      });
      const result = await apiGet<Paginated<StaffRow>>(`/users?${params.toString()}`);
      setRows(result.data);
      setTotal(result.total);
      setLastPage(result.last_page);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا");
    } finally {
      setLoading(false);
    }
  }, [filters, page, refresh]);

  useEffect(() => {
    load();
  }, [load]);

  const writeFiltersToUrl = (next: typeof emptyFilters) => {
    const params = new URLSearchParams();
    Object.entries(next).forEach(([key, value]) => {
      if (!value) return;
      if (key === "branch_id" && value === String(getActiveBranchId() ?? "")) return;
      params.set(key, value);
    });
    const suffix = params.toString() ? `?${params.toString()}` : "";
    router.replace(`/staff${suffix}`);
  };

  const impersonate = async (id: number) => {
    setError(null);
    try {
      await startStaffImpersonation(id);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "ورود به این کاربر ناموفق بود.");
    }
  };

  const confirmDelete = async () => {
    if (deleteId == null) return;
    setDeleting(true);
    try {
      await apiDelete(`/users/${deleteId}`);
      setDeleteId(null);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در حذف");
    } finally {
      setDeleting(false);
    }
  };

  const displayName = (u: StaffRow) =>
    [u.first_name, u.last_name].filter(Boolean).join(" ") || u.name;

  return (
    <AppShell title="کارمندان" subtitle="مدیریت پرسنل">
      {error ? <Alert tone="error">{error}</Alert> : null}

      <div className="mb-4 rounded-2xl border border-[var(--border)] bg-white shadow-card">
        <AdvancedSearchToggle open={showSearch} onToggle={() => setShowSearch(!showSearch)} />
        {showSearch ? (
          <div className="grid gap-3 border-t border-[var(--border)] p-4 sm:grid-cols-2 lg:grid-cols-4">
            <Field label="شعبه / مدرسه">
              <Select
                value={filters.branch_id}
                onChange={(e) => setFilters({ ...filters, branch_id: e.target.value })}
              >
                <option value="">همه</option>
                {branches.map((b) => (
                  <option key={b.id} value={b.id}>{b.name}</option>
                ))}
              </Select>
            </Field>
            {[
              ["name", "نام / نام خانوادگی"],
              ["national_code", "کد ملی"],
              ["personnel_code", "کد پرسنلی"],
              ["mobile", "موبایل"],
            ].map(([key, label]) => (
              <Field key={key} label={label}>
                <Input
                  value={filters[key as keyof typeof filters]}
                  onChange={(e) => setFilters({ ...filters, [key]: e.target.value })}
                />
              </Field>
            ))}
            <Field label="نقش">
              <Select
                value={filters.role}
                onChange={(e) => setFilters({ ...filters, role: e.target.value })}
              >
                <option value="">همه</option>
                {roleOptions.map((role) => (
                  <option key={role.id} value={role.name}>{role.label_fa}</option>
                ))}
                {filters.role && !roleOptions.some((role) => role.name === filters.role) ? (
                  <option value={filters.role}>{filters.role}</option>
                ) : null}
              </Select>
            </Field>
            <Field label="نوع همکاری">
              <Select
                value={filters.employment_type}
                onChange={(e) => setFilters({ ...filters, employment_type: e.target.value })}
              >
                <option value="">همه</option>
                <option value="official">رسمی</option>
                <option value="contractual">قراردادی</option>
              </Select>
            </Field>
            <Field label="وضعیت">
              <Select
                value={filters.is_active}
                onChange={(e) => setFilters({ ...filters, is_active: e.target.value })}
              >
                <option value="">همه</option>
                <option value="true">فعال</option>
                <option value="false">غیرفعال</option>
              </Select>
            </Field>
            <div className="flex items-end gap-2 sm:col-span-2 lg:col-span-4">
              <Button onClick={() => { setPage(1); writeFiltersToUrl(filters); setRefresh((r) => r + 1); }}>جستجو</Button>
              <Button
                variant="secondary"
                onClick={() => {
                  const cleared = {
                    ...emptyFilters,
                    branch_id: String(getActiveBranchId() ?? ""),
                  };
                  setFilters(cleared);
                  setPage(1);
                  writeFiltersToUrl(cleared);
                }}
              >
                پاک کردن فیلترها
              </Button>
            </div>
          </div>
        ) : null}
      </div>

      <PageHeader
        title="فهرست کارمندان"
        subtitle={`تعداد: ${total}`}
        actions={
          <>
            <ListExportActions
              exportPath="/users/export"
              filters={filters}
              filenameBase="staff-export"
              onError={setError}
            />
            {hasPermission("iam.user.manage") ? (
              <Link href="/staff/import">
                <Button variant="secondary">ورود از اکسل</Button>
              </Link>
            ) : null}
            <Link href="/staff/new">
              <Button>کاربر جدید</Button>
            </Link>
            <Link href="/roles">
              <Button variant="secondary">سطوح دسترسی</Button>
            </Link>
          </>
        }
      />

      <DataTable
        loading={loading}
        columns={[
          { key: "idx", label: "#" },
          { key: "first", label: "نام" },
          { key: "last", label: "نام خانوادگی" },
          { key: "pass", label: "رمز اولیه" },
          { key: "nc", label: "کد ملی" },
          { key: "status", label: "وضعیت" },
          { key: "mobile", label: "موبایل" },
          { key: "emp", label: "نوع همکاری" },
          { key: "roles", label: "نقش" },
          { key: "ops", label: "عملیات" },
        ]}
      >
        {rows.length === 0 ? (
          <DataTableEmpty colSpan={10} />
        ) : (
          rows.map((u, i) => (
            <tr key={u.id} className="hover:bg-slate-50">
              <td className="px-3 py-2">{(page - 1) * 20 + i + 1}</td>
              <td className="px-3 py-2 font-medium">{u.first_name || displayName(u).split(" ")[0] || "—"}</td>
              <td className="px-3 py-2 font-medium">{u.last_name || "—"}</td>
              <td className="px-3 py-2 font-mono text-xs">{u.initial_password ?? "—"}</td>
              <td className="px-3 py-2">{u.national_code ?? "—"}</td>
              <td className="px-3 py-2">
                <span
                  className={`rounded-full px-2 py-0.5 text-xs font-semibold ${
                    u.is_active ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"
                  }`}
                >
                  {u.is_active ? "فعال" : "غیرفعال"}
                </span>
              </td>
              <td className="px-3 py-2">{u.mobile ?? "—"}</td>
              <td className="px-3 py-2">{u.employment_type_label ?? "—"}</td>
              <td className="px-3 py-2 text-xs">
                {(() => {
                  const roles = uniqueStaffRoles(u);
                  if (roles.length === 0) return "—";
                  return (
                    <span className="flex flex-col items-end gap-0.5">
                      {roles.map((role) =>
                        role.role_name ? (
                          <Link
                            key={role.role_name}
                            href={`/staff?role=${encodeURIComponent(role.role_name)}`}
                            className="block whitespace-nowrap text-primary hover:underline"
                          >
                            {role.role_label}
                          </Link>
                        ) : (
                          <span key={role.role_label} className="block whitespace-nowrap">
                            {role.role_label}
                          </span>
                        ),
                      )}
                    </span>
                  );
                })()}
              </td>
              <td className="px-3 py-2">
                <ActionMenu
                  items={[
                    { label: "مشاهده", href: `/staff/${u.id}`, tone: "primary" },
                    { label: "ویرایش", href: `/staff/${u.id}/edit` },
                    { label: "ورود با این کاربر", onClick: () => void impersonate(u.id) },
                    { label: "نقش‌ها", href: `/staff/${u.id}/roles` },
                    {
                      label: "بازنشانی رمز",
                      href: `/staff/${u.id}/reset-password`,
                    },
                    {
                      label: u.is_active ? "غیرفعال" : "فعال",
                      onClick: async () => {
                        await apiPost(`/users/${u.id}/toggle-active`, {});
                        await load();
                      },
                    },
                    {
                      label: "حذف",
                      tone: "danger",
                      onClick: () => setDeleteId(u.id),
                    },
                  ]}
                />
              </td>
            </tr>
          ))
        )}
      </DataTable>

      <Pagination page={page} lastPage={lastPage} onPageChange={setPage} />

      <ConfirmDialog
        open={deleteId != null}
        title="حذف کارمند"
        message="آیا از حذف این کارمند مطمئن هستید؟ این عملیات قابل بازگشت نیست."
        loading={deleting}
        onCancel={() => setDeleteId(null)}
        onConfirm={confirmDelete}
      />
    </AppShell>
  );
}
