"use client";

import { useEffect, useRef, useState, type FormEvent } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/Icon";
import { api } from "@/lib/client";
import { useT } from "@/components/providers";

export interface MemberListItem {
  id: number;
  public_uuid: string;
  full_name: string;
  governorate_name: string | null;
  formal_status_ar: string;
  formal_status_code: string;
  suspension_until: string | null;
  suspension_expired: boolean;
  is_demo: boolean;
  has_contact: boolean;
  verified_at: string | null;
  secretariat_id: number | null;
  secretariat_name: string | null;
}

export function MembersManager({
  initialItems,
  initialTotal,
  canManage,
  canSeeContact,
}: {
  initialItems: MemberListItem[];
  initialTotal: number;
  canManage: boolean;
  canSeeContact: boolean;
}) {
  const router = useRouter();
  const [items, setItems] = useState(initialItems);
  const [total, setTotal] = useState(initialTotal);
  const [search, setSearch] = useState("");
  const [secretariatId, setSecretariatId] = useState("");
  const [secretariats, setSecretariats] = useState<{ id: number; name_ar: string; members: number }[]>([]);
  const importFile = useRef<HTMLInputElement>(null);
  const [importState, setImportState] = useState<{ total: number; valid: number; errorCount: number; errors: { row: number; name: string; reason: string }[] } | null>(null);
  const [pendingFile, setPendingFile] = useState<File | null>(null);
  const [message, setMessage] = useState<{ kind: "ok" | "err"; text: string } | null>(null);
  const [busy, setBusy] = useState(false);
  const { t } = useT();

  useEffect(() => {
    api<{ items: { id: number; name_ar: string; members: number }[] }>("/api/members/secretariats").then((res) => {
      if (res.status === 200 && res.data) setSecretariats(res.data.items);
    });
  }, []);

  async function refresh(q = search, sec = secretariatId) {
    const res = await api<{ items: MemberListItem[]; total: number }>(
      `/api/members?pageSize=50${q ? `&q=${encodeURIComponent(q)}` : ""}${sec ? `&secretariatId=${sec}` : ""}`,
    );
    if (res.status === 200 && res.data) {
      setItems(res.data.items);
      setTotal(res.data.total);
    }
  }

  async function onSecretariatChange(v: string) {
    setSecretariatId(v);
    setBusy(true);
    await refresh(search, v);
    setBusy(false);
  }

  async function onImportFile(f: File) {
    setBusy(true);
    setMessage(null);
    const csrf = await (await fetch("/api/auth/csrf")).headers.getSetCookie().map(c => c.split(";")[0]).join("; ");
    const token = /bousla_csrf=([^;]+)/.exec(csrf)?.[1] ?? "";
    const res = await fetch("/api/members/import-preview", {
      method: "POST",
      headers: { "content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "x-csrf-token": token },
      body: f,
      credentials: "same-origin",
    });
    setBusy(false);
    if (res.ok) {
      const data = (await res.json()) as { total: number; valid: number; errorCount: number; errors: { row: number; name: string; reason: string }[] };
      setPendingFile(f);
      setImportState(data);
    } else {
      setMessage({ kind: "err", text: t.myProfile.opFailed });
    }
  }

  async function confirmImport() {
    if (!pendingFile) return;
    setBusy(true);
    const csrf = await (await fetch("/api/auth/csrf")).headers.getSetCookie().map(c => c.split(";")[0]).join("; ");
    const token = /bousla_csrf=([^;]+)/.exec(csrf)?.[1] ?? "";
    const res = await fetch("/api/members/import-commit", {
      method: "POST",
      headers: { "content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "x-csrf-token": token },
      body: pendingFile,
      credentials: "same-origin",
    });
    setBusy(false);
    if (res.ok) {
      setMessage({ kind: "ok", text: t.members.imported });
      setImportState(null);
      setPendingFile(null);
      await refresh();
    } else {
      const body = (await res.json()) as { errors?: { reason: string }[] };
      setMessage({ kind: "err", text: (body.errors ?? []).map((x) => x.reason).join(" · ") || t.members.opFailed });
    }
  }

  async function onSearch(e: FormEvent) {
    e.preventDefault();
    setBusy(true);
    await refresh();
    setBusy(false);
  }

  async function createMember(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setMessage(null);
    const form = new FormData(e.currentTarget);
    const body = {
      fullName: String(form.get("fullName") ?? "").trim(),
      governorateId: form.get("governorateId") ? Number(form.get("governorateId")) : null,
      membershipNo: String(form.get("membershipNo") ?? "").trim() || null,
    };
    const res = await api<{ public_uuid: string }>("/api/members", "POST", body);
    if (res.status === 201) {
      setMessage({ kind: "ok", text: t.members.memberCreated });
      (e.target as HTMLFormElement).reset();
      await refresh();
      router.refresh();
    } else {
      setMessage({ kind: "err", text: res.error ?? t.members.opFailed });
    }
  }

  return (
    <div className="space-y-6">
      {message && (
        <div
          role="status"
          className={`rounded-lg border px-4 py-2.5 text-sm ${
            message.kind === "ok" ? "border-emerald-200 bg-emerald-50 text-emerald-800" : "border-red-200 bg-red-50 text-red-700"
          }`}
        >
          {message.text}
        </div>
      )}

      {importState && (
        <div role="dialog" aria-label={t.members.importTitle} className="rounded-xl border border-bousla-200 bg-white p-5 shadow-card">
          <h3 className="font-bold text-slate-900">{t.members.importTitle}</h3>
          <a href="/api/members/import-template" className="ml-2 text-xs font-bold text-bousla-700 hover:underline">{t.members.downloadTemplate}</a>
          <p className="numeric mt-1 text-sm text-slate-600">
            {t.members.importReady}: {importState.valid} / {importState.total}
          </p>
          {importState.errorCount > 0 && (
            <div className="mt-3 rounded-lg border border-red-200 bg-red-50 p-3">
              <p className="text-xs font-bold text-red-700">{t.members.importErrors} ({importState.errorCount}):</p>
              <ul className="mt-1 max-h-40 space-y-1 overflow-y-auto text-xs text-red-700">
                {importState.errors.map((e2) => (
                  <li key={e2.row} dir="auto">صف {e2.row} — {e2.name}: {e2.reason}</li>
                ))}
              </ul>
            </div>
          )}
          <div className="mt-4 flex gap-2">
            {importState.errorCount === 0 && (
              <button type="button" disabled={busy} onClick={() => void confirmImport()} className="rounded-lg bg-bousla-700 px-4 py-2 text-sm font-bold text-white hover:bg-bousla-800 disabled:opacity-60">
                {t.members.confirmImport}
              </button>
            )}
            <button type="button" onClick={() => { setImportState(null); setPendingFile(null); }} className="rounded-lg border border-slate-200 px-4 py-2 text-sm font-bold text-slate-600 hover:bg-slate-50">
              {t.common.cancel}
            </button>
          </div>
        </div>
      )}

      {canManage && (
        <section className="rounded-xl border border-slate-200 bg-white p-5 shadow-card">
          <h2 className="mb-4 flex items-center gap-2 font-bold text-slate-900">
            <Icon name="users" className="h-5 w-5 text-bousla-700" /> {t.members.addMember}
          </h2>
          <form onSubmit={createMember} className="grid gap-4 sm:grid-cols-3">
            <div>
              <label htmlFor="m-name" className="mb-1 block text-xs font-bold text-slate-600">{t.members.fullName}</label>
              <input id="m-name" name="fullName" required minLength={3} className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm outline-none focus:border-bousla-500 focus:ring-2 focus:ring-bousla-100" />
            </div>
            <div>
              <label htmlFor="m-gov" className="mb-1 block text-xs font-bold text-slate-600">{t.members.governorate} ({t.common.optional})</label>
              <input id="m-gov" name="governorateId" type="number" min={1} max={27} placeholder="1–27" className="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm outline-none focus:border-bousla-500 focus:ring-2 focus:ring-bousla-100" />
            </div>
            <div>
              <label htmlFor="m-no" className="mb-1 block text-xs font-bold text-slate-600">{t.members.membershipNo} ({t.common.optional})</label>
              <input id="m-no" name="membershipNo" type="number" min={1} dir="ltr" className="w-full rounded-lg border border-slate-300 px-3 py-2 text-left text-sm outline-none focus:border-bousla-500 focus:ring-2 focus:ring-bousla-100" />
            </div>
            <div className="flex items-end">
              <button type="submit" className="w-full rounded-lg bg-bousla-700 px-4 py-2 text-sm font-bold text-white transition hover:bg-bousla-800">{t.members.createMember}</button>
            </div>
          </form>
        </section>
      )}

      <section className="rounded-xl border border-slate-200 bg-white shadow-card">
        <div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-100 px-5 py-4">
          <h2 className="font-bold text-slate-900">
            {t.nav.members} <span className="numeric text-sm font-normal text-slate-400">({total})</span>
          </h2>
          <form onSubmit={onSearch} className="flex gap-2">
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder={t.common.search + "…"}
              aria-label={t.common.search}
              className="w-48 rounded-lg border border-slate-300 px-3 py-1.5 text-sm outline-none focus:border-bousla-500 focus:ring-2 focus:ring-bousla-100"
            />
            <button type="submit" disabled={busy} className="rounded-lg border border-bousla-200 px-3 py-1.5 text-xs font-bold text-bousla-800 hover:bg-bousla-50 disabled:opacity-50">
              {t.common.search}
            </button>
          </form>
            <select
              value={secretariatId}
              onChange={(e) => void onSecretariatChange(e.target.value)}
              aria-label={t.members.secretariat}
              className="rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm outline-none focus:border-bousla-500 focus:ring-2 focus:ring-bousla-100"
            >
              <option value="">{t.members.allSecretariats}</option>
              {secretariats.map((sec) => (
                <option key={sec.id} value={sec.id}>
                  {sec.name_ar} ({sec.members})
                </option>
              ))}
            </select>
            <a href="/api/members/export" className="rounded-lg border border-bousla-200 px-3 py-2 text-xs font-bold text-bousla-800 hover:bg-bousla-50">{t.members.exportBtn}</a>
            <input
              ref={importFile}
              type="file"
              accept=".xlsx"
              className="hidden"
              onChange={(e) => { const f = e.target.files?.[0]; if (f) void onImportFile(f); e.target.value = ""; }}
            />
            <button
              type="button"
              disabled={busy}
              onClick={() => importFile.current?.click()}
              className="rounded-lg border border-slate-200 px-3 py-2 text-xs font-bold text-slate-600 hover:bg-slate-50 disabled:opacity-50"
            >
              {t.members.importTitle}
            </button>
        </div>
        <div className="overflow-x-auto">
          <table className="w-full min-w-[680px] text-sm">
            <thead>
              <tr className="border-b border-slate-200 bg-slate-50 text-right text-xs font-bold text-slate-500">
                <th className="px-4 py-3">{t.members.fullName}</th>
                <th className="px-4 py-3">{t.members.governorate}</th>
                <th className="px-4 py-3">{t.members.formalStatus}</th>
                <th className="px-4 py-3">{t.members.secretariat}</th>
                <th className="px-4 py-3">{t.members.contact}</th>
                <th className="px-4 py-3"></th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {items.length === 0 && (
                <tr>
                  <td colSpan={6} className="px-4 py-10 text-center text-slate-400">
                    {t.members.noRecords}
                  </td>
                </tr>
              )}
              {items.map((m) => (
                <tr key={m.public_uuid} className="hover:bg-slate-50/60">
                  <td className="px-4 py-3">
                    <p className="font-bold text-slate-800" dir="auto">
                      {m.full_name}
                      {m.is_demo && <span className="mr-2 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-bold text-amber-700">DEMO</span>}
                    </p>
                  </td>
                  <td className="px-4 py-3 text-slate-600">{m.governorate_name ?? t.members.notSpecified}</td>
                  <td className="px-4 py-3">
                    <span
                      className={`rounded-full px-2.5 py-0.5 text-[11px] font-bold ${
                        m.formal_status_code === "suspended" ? "bg-red-50 text-red-700" : "bg-slate-100 text-slate-600"
                      }`}
                    >
                      {m.formal_status_ar}
                      {m.formal_status_code === "suspended" && m.suspension_until && ` — ${t.members.until} ${m.suspension_until}`}
                      {m.suspension_expired && " (" + t.members.suspensionExpired.slice(0, 18) + ")"}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-slate-600">{m.secretariat_name ? (
                    <Link href={`/dashboard/structure/${m.secretariat_id}`} className="text-bousla-700 hover:underline" dir="auto">{m.secretariat_name}</Link>
                  ) : <span className="text-slate-300">{t.members.secretariatNotSet}</span>}</td>
                  <td className="px-4 py-3 text-xs text-slate-400">
                    {m.has_contact ? (canSeeContact ? t.members.recordedRevealable : t.members.recordedMasked) : t.members.notRecorded}
                  </td>
                  <td className="px-4 py-3">
                    <Link href={`/dashboard/members/${m.public_uuid}`} className="text-sm font-bold text-bousla-700 hover:text-bousla-800">
                      {t.members.openFile}
                    </Link>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>
    </div>
  );
}
