"use client";

/**
 * 2026-11-11 — Companies → "⇄ Transfer" (admins / coordinators).
 * Hand one month of scheduled audits (Initial by default) to a Job Documents user, e.g.
 * "August Initial audits → Tehreem". That user then sees ONLY the companies of the transferred audits in
 * Companies, and only those audits in Create Job. Taking audits back puts the user on the normal
 * Initial-audit list again (when nothing is left transferred to her).
 */
import React, { useEffect, useMemo, useState } from "react";
import { createPortal } from "react-dom";
import toast from "react-hot-toast";
import {
  getTransferPreview,
  getTransferSummary,
  getTransferUsers,
  removeTransfers,
  transferAudits,
  type TransferAudit,
  type TransferGroup,
  type TransferUser,
} from "@/lib/api/company-documents.api";

const C = {
  brand: "#760E9E",
  border: "#e6e8ee",
  muted: "#667085",
  text: "#101828",
};

const thisMonth = () => new Date().toISOString().slice(0, 7);
const monthLabel = (m: string) => {
  const [y, mo] = m.split("-").map(Number);
  return new Date(Date.UTC(y, (mo || 1) - 1, 1)).toLocaleDateString("en-GB", { month: "long", year: "numeric", timeZone: "UTC" });
};
const fmtDay = (d?: string | null) =>
  d ? new Date(d + "T00:00:00").toLocaleDateString("en-GB", { day: "2-digit", month: "short" }) : "—";

export default function TransferAuditsModal({ onClose, onChanged }: { onClose: () => void; onChanged?: () => void }) {
  const [users, setUsers] = useState<TransferUser[]>([]);
  const [toUser, setToUser] = useState<number | "">("");
  const [month, setMonth] = useState(thisMonth());
  const [type, setType] = useState<"INITIAL" | "ALL">("INITIAL");
  const [audits, setAudits] = useState<TransferAudit[]>([]);
  const [ready, setReady] = useState(true);
  const [sel, setSel] = useState<Set<number>>(new Set());
  const [note, setNote] = useState("");
  const [loading, setLoading] = useState(false);
  const [busy, setBusy] = useState(false);
  const [groups, setGroups] = useState<TransferGroup[]>([]);
  const [q, setQ] = useState("");

  const loadSummary = () =>
    getTransferSummary()
      .then((r) => {
        setGroups(r.groups);
        if (!r.ready) setReady(false);
      })
      .catch(() => undefined);

  useEffect(() => {
    getTransferUsers()
      .then((u) => {
        setUsers(u);
        const first = u.find((x) => x.job_docs);
        if (first) setToUser(first.id);
      })
      .catch((e) => toast.error(e?.message || "Could not load users"));
    loadSummary();
  }, []);

  const loadPreview = () => {
    if (!/^\d{4}-\d{2}$/.test(month)) return;
    setLoading(true);
    getTransferPreview(month, type)
      .then((r) => {
        setReady(r.ready);
        setAudits(r.audits);
        // pre-tick the audits that are not yet with the chosen user
        setSel(new Set(r.audits.filter((a) => a.assigned_to !== toUser).map((a) => a.id)));
      })
      .catch((e) => toast.error(e?.message || "Could not load audits"))
      .finally(() => setLoading(false));
  };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(loadPreview, [month, type]);

  const shown = useMemo(() => {
    const s = q.trim().toLowerCase();
    return s ? audits.filter((a) => `${a.company_name} ${a.audit_code} ${a.lead_auditor ?? ""}`.toLowerCase().includes(s)) : audits;
  }, [audits, q]);
  const user = users.find((u) => u.id === toUser);
  const nSel = audits.filter((a) => sel.has(a.id)).length;
  const companiesSel = new Set(audits.filter((a) => sel.has(a.id)).map((a) => a.company_id)).size;
  const allShownOn = shown.length > 0 && shown.every((a) => sel.has(a.id));

  const toggle = (id: number) =>
    setSel((s) => {
      const n = new Set(s);
      if (n.has(id)) n.delete(id);
      else n.add(id);
      return n;
    });

  const doTransfer = async () => {
    if (!toUser) return toast.error("Choose the user");
    if (!nSel) return toast.error("Tick at least one audit");
    setBusy(true);
    try {
      const r = await transferAudits(Number(toUser), [...sel], note || undefined);
      toast.success(`${r.transferred} audit(s) of ${monthLabel(month)} transferred to ${user?.name ?? "the user"}`);
      setNote("");
      loadPreview();
      loadSummary();
      onChanged?.();
    } catch (e: any) {
      toast.error(e?.message || "Transfer failed");
    } finally {
      setBusy(false);
    }
  };

  const doRemove = async (ids: number[], label: string) => {
    if (!ids.length) return;
    if (!window.confirm(`Take back ${ids.length} audit(s) (${label})?`)) return;
    setBusy(true);
    try {
      const r = await removeTransfers(ids);
      toast.success(`${r.removed} audit(s) taken back`);
      loadPreview();
      loadSummary();
      onChanged?.();
    } catch (e: any) {
      toast.error(e?.message || "Could not take the audits back");
    } finally {
      setBusy(false);
    }
  };

  const selectedAssigned = audits.filter((a) => sel.has(a.id) && a.assigned_to).map((a) => a.id);

  const body = (
    <div
      onMouseDown={(e) => e.target === e.currentTarget && !busy && onClose()}
      style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(16,24,40,.45)", display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "32px 16px", overflowY: "auto" }}
    >
      <div style={{ width: "min(1100px, 100%)", background: "#fff", borderRadius: 14, boxShadow: "0 24px 48px -12px rgba(16,24,40,.35)", overflow: "hidden" }}>
        {/* header */}
        <div style={{ padding: "16px 20px", borderBottom: `1px solid ${C.border}`, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
          <div>
            <h2 style={{ margin: 0, fontSize: 18, color: C.text }}>⇄ Transfer audits</h2>
            <p style={{ margin: "2px 0 0", fontSize: 12.5, color: C.muted }}>
              Give a month of scheduled audits to one user. That user then sees only those companies in Companies and only those audits in Create Job.
            </p>
          </div>
          <button type="button" onClick={onClose} disabled={busy} style={{ border: "none", background: "none", fontSize: 22, cursor: "pointer", color: C.muted }} aria-label="Close">
            ×
          </button>
        </div>

        {!ready && (
          <div style={{ margin: "14px 20px 0", padding: "10px 12px", borderRadius: 10, background: "#fffbeb", border: "1px solid #fcd34d", fontSize: 13, color: "#92400e" }}>
            <b>Transfer is not set up on the server yet.</b> The server admin must run once, in the CRM backend folder:{" "}
            <code style={{ background: "#fef3c7", padding: "1px 5px", borderRadius: 4 }}>node src/company-documents/migrations/run-002.js</code>
          </div>
        )}

        {/* controls */}
        <div style={{ padding: "14px 20px", display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: 12, alignItems: "end" }}>
          <label style={lbl}>
            Transfer to
            <select value={toUser} onChange={(e) => setToUser(e.target.value ? Number(e.target.value) : "")} style={inp}>
              <option value="">— choose user —</option>
              {users.map((u) => (
                <option key={u.id} value={u.id}>
                  {u.name}
                  {u.job_docs ? " ★ Job Documents" : ""}
                  {u.transferred ? ` (${u.transferred} now)` : ""}
                </option>
              ))}
            </select>
          </label>
          <label style={lbl}>
            Audit month
            <input type="month" value={month} onChange={(e) => setMonth(e.target.value)} style={inp} />
          </label>
          <label style={lbl}>
            Audits
            <select value={type} onChange={(e) => setType(e.target.value as "INITIAL" | "ALL")} style={inp}>
              <option value="INITIAL">Initial audits only</option>
              <option value="ALL">All audit types</option>
            </select>
          </label>
          <label style={lbl}>
            Search
            <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Company, audit code, auditor" style={inp} />
          </label>
        </div>
        {user && !user.job_docs && (
          <div style={{ margin: "0 20px 10px", fontSize: 12.5, color: "#b45309" }}>
            ⚠ {user.name} has no Job Documents permission — give the &quot;Job Documents&quot; role first, otherwise the transfer has no effect for this user.
          </div>
        )}

        {/* audits table */}
        <div style={{ margin: "0 20px", border: `1px solid ${C.border}`, borderRadius: 10, maxHeight: 420, overflow: "auto" }}>
          <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 12.5 }}>
            <thead style={{ position: "sticky", top: 0, background: "#f9fafb", zIndex: 1 }}>
              <tr>
                <th style={th}>
                  <input
                    type="checkbox"
                    checked={allShownOn}
                    onChange={() =>
                      setSel((s) => {
                        const n = new Set(s);
                        shown.forEach((a) => (allShownOn ? n.delete(a.id) : n.add(a.id)));
                        return n;
                      })
                    }
                  />
                </th>
                <th style={th}>Date</th>
                <th style={th}>Audit</th>
                <th style={th}>Company</th>
                <th style={th}>Standards</th>
                <th style={th}>Lead auditor</th>
                <th style={th}>Docs</th>
                <th style={th}>Now with</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr>
                  <td colSpan={8} style={{ padding: 30, textAlign: "center", color: C.muted }}>Loading…</td>
                </tr>
              ) : shown.length === 0 ? (
                <tr>
                  <td colSpan={8} style={{ padding: 30, textAlign: "center", color: C.muted }}>
                    No {type === "INITIAL" ? "Initial " : ""}audits scheduled in {monthLabel(month)}.
                  </td>
                </tr>
              ) : (
                shown.map((a) => {
                  const on = sel.has(a.id);
                  return (
                    <tr key={a.id} onClick={() => toggle(a.id)} style={{ cursor: "pointer", background: on ? "#faf5ff" : undefined, borderTop: `1px solid #f2f4f7` }}>
                      <td style={td}>
                        <input type="checkbox" checked={on} onChange={() => toggle(a.id)} onClick={(e) => e.stopPropagation()} />
                      </td>
                      <td style={{ ...td, whiteSpace: "nowrap" }}>{fmtDay(a.schedule_date)}</td>
                      <td style={{ ...td, fontFamily: "monospace", fontSize: 11.5 }}>
                        {a.audit_code}
                        <div style={{ fontFamily: "inherit", color: C.muted, fontSize: 10.5 }}>
                          {a.audit_stage || a.audit_type} · {a.status}
                        </div>
                      </td>
                      <td style={{ ...td, fontWeight: 600, color: C.text }}>{a.company_name}</td>
                      <td style={td}>{a.standards.join(", ") || "—"}</td>
                      <td style={td}>{a.lead_auditor || "—"}</td>
                      <td style={{ ...td, textAlign: "center" }}>{a.documents ? <span style={{ color: "#047857", fontWeight: 700 }}>{a.documents}</span> : "—"}</td>
                      <td style={td}>
                        {a.assigned_to_name ? (
                          <span style={{ padding: "2px 7px", borderRadius: 999, background: a.assigned_to === toUser ? "#dcfce7" : "#f2f4f7", color: a.assigned_to === toUser ? "#166534" : "#344054", fontWeight: 600, fontSize: 11.5 }}>
                            {a.assigned_to_name}
                          </span>
                        ) : (
                          <span style={{ color: "#98a2b3" }}>not transferred</span>
                        )}
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>

        {/* action bar */}
        <div style={{ padding: "12px 20px", display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <input value={note} onChange={(e) => setNote(e.target.value)} placeholder="Note (optional)" style={{ ...inp, flex: "1 1 220px", marginTop: 0 }} />
          {selectedAssigned.length > 0 && (
            <button type="button" disabled={busy || !ready} onClick={() => doRemove(selectedAssigned, "selected")} style={btnGhost}>
              Take back {selectedAssigned.length}
            </button>
          )}
          <button type="button" disabled={busy || !ready || !nSel || !toUser} onClick={doTransfer} style={{ ...btnPrimary, opacity: busy || !ready || !nSel || !toUser ? 0.55 : 1 }}>
            {busy ? "Working…" : `Transfer ${nSel} audit${nSel === 1 ? "" : "s"} (${companiesSel} compan${companiesSel === 1 ? "y" : "ies"}) to ${user?.name ?? "…"}`}
          </button>
        </div>

        {/* current transfers */}
        <div style={{ padding: "4px 20px 20px" }}>
          <h3 style={{ fontSize: 14, margin: "8px 0", color: C.text }}>Current transfers</h3>
          {groups.length === 0 ? (
            <p style={{ fontSize: 12.5, color: C.muted, margin: 0 }}>Nothing transferred yet — Job Documents users see every company with an Initial audit.</p>
          ) : (
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
              {groups.map((g) => (
                <div key={`${g.user_id}-${g.month}`} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 10px", border: `1px solid ${C.border}`, borderRadius: 10, fontSize: 12.5 }}>
                  <span>
                    <b>{g.name}</b> · {monthLabel(g.month)} · {g.audits} audit{g.audits === 1 ? "" : "s"} / {g.companies} compan{g.companies === 1 ? "y" : "ies"}
                  </span>
                  <button type="button" style={{ ...btnGhost, padding: "3px 8px", fontSize: 11.5 }} disabled={busy} onClick={() => setMonth(g.month)}>
                    Show
                  </button>
                  <button type="button" style={{ ...btnGhost, padding: "3px 8px", fontSize: 11.5, color: "#b42318", borderColor: "#fecdca" }} disabled={busy} onClick={() => doRemove(g.row_ids, `${g.name}, ${monthLabel(g.month)}`)}>
                    Take back
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
  return typeof document !== "undefined" ? createPortal(body, document.body) : body;
}

const lbl: React.CSSProperties = { display: "flex", flexDirection: "column", gap: 4, fontSize: 12, fontWeight: 600, color: "#344054" };
const inp: React.CSSProperties = { marginTop: 2, height: 36, padding: "0 10px", border: "1px solid #d0d5dd", borderRadius: 8, fontSize: 13, background: "#fff", color: "#101828" };
const th: React.CSSProperties = { textAlign: "left", padding: "8px 10px", fontSize: 11, fontWeight: 700, color: "#475467", textTransform: "uppercase", letterSpacing: ".03em", borderBottom: "1px solid #e6e8ee", whiteSpace: "nowrap" };
const td: React.CSSProperties = { padding: "7px 10px", verticalAlign: "top", color: "#344054" };
const btnPrimary: React.CSSProperties = { height: 36, padding: "0 14px", border: "none", borderRadius: 8, background: "#760E9E", color: "#fff", fontWeight: 700, fontSize: 13, cursor: "pointer" };
const btnGhost: React.CSSProperties = { height: 36, padding: "0 12px", border: "1px solid #d0d5dd", borderRadius: 8, background: "#fff", color: "#344054", fontWeight: 600, fontSize: 13, cursor: "pointer" };
