"use client";

import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import type { CandidateSource, CandidateType, CrewStatus } from "@prisma/client";
import { Badge } from "@/components/ui/badge";
import { AdminDialog } from "@/components/ui/admin-dialog";
import { RowActionsMenu, RowActionsItem, RowActionsDestructiveItem, RowActionsSeparator } from "@/components/ui/row-actions-menu";
import { DeleteConfirmDialog } from "@/components/ui/delete-confirm-dialog";
import { createCrewMember, updateCrewMember, deleteCrewMember, placeCrew } from "./actions";

const INPUT = "w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20";
const BTN = "rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60";
const SECONDARY = "rounded-lg border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50";

const STATUSES: CrewStatus[] = ["PROSPECT", "CANDIDATE", "EMPLOYEE", "EX_HAND", "BLACKLISTED"];
const SOURCES: CandidateSource[] = ["CAREERS", "EX_HAND", "WALK_IN", "REFERRAL", "OTHER"];
const label = (s: string) => s.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (m) => m.toUpperCase());

type Opt = { id: string; name: string };
type RankOpt = { id: string; code: string; name: string };
type Crew = {
  id: string; name: string; status: CrewStatus; type: CandidateType; source: CandidateSource;
  email: string | null; phone: string | null; employeeId: string | null;
  appliedRankId: string | null; currentRankId: string | null; currentRank: string | null;
  experienceMonths: number; hasActiveAssignment: boolean; removable: boolean;
};

const STATUS_VARIANT: Record<CrewStatus, "outline" | "default" | "success" | "secondary" | "danger"> = {
  PROSPECT: "outline", CANDIDATE: "default", EMPLOYEE: "success", EX_HAND: "secondary", BLACKLISTED: "danger",
};

export function AdminCrewManager({ crew, ranks, vessels, sites }: { crew: Crew[]; ranks: RankOpt[]; vessels: Opt[]; sites: Opt[] }) {
  const [search, setSearch] = useState("");
  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return crew.filter((c) => !q || `${c.name} ${c.employeeId ?? ""}`.toLowerCase().includes(q));
  }, [crew, search]);

  return (
    <div>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold text-neutral-900">Crew management</h1>
          <p className="text-sm text-neutral-500 mt-0.5">{crew.length} crew records · create, edit, place onto a vessel/site, or remove</p>
        </div>
        <CrewFormButton ranks={ranks} />
      </div>

      <input className={`${INPUT} mb-4 max-w-sm`} placeholder="Search name or employee no…" value={search} onChange={(e) => setSearch(e.target.value)} />

      <div className="rounded-lg border border-neutral-200 bg-white overflow-hidden">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-neutral-200 bg-neutral-50 text-left text-xs font-semibold text-neutral-500 uppercase tracking-wide">
              <th className="px-4 py-3">Name</th>
              <th className="px-4 py-3">Employee</th>
              <th className="px-4 py-3">Status</th>
              <th className="px-4 py-3">Rank</th>
              <th className="px-4 py-3 w-12"></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 ? (
              <tr><td colSpan={5} className="px-4 py-12 text-center text-neutral-400">No crew records.</td></tr>
            ) : filtered.map((c) => <Row key={c.id} c={c} ranks={ranks} vessels={vessels} sites={sites} />)}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function Row({ c, ranks, vessels, sites }: { c: Crew; ranks: RankOpt[]; vessels: Opt[]; sites: Opt[] }) {
  const [editOpen, setEditOpen] = useState(false);
  const [placeOpen, setPlaceOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  return (
    <tr className="border-b border-neutral-100 last:border-0 hover:bg-neutral-50">
      <td className="px-4 py-3 font-medium text-neutral-900">{c.name}</td>
      <td className="px-4 py-3 font-mono text-xs text-neutral-600">{c.employeeId ?? "—"}</td>
      <td className="px-4 py-3"><Badge variant={STATUS_VARIANT[c.status]}>{label(c.status)}</Badge></td>
      <td className="px-4 py-3 text-neutral-700">{c.currentRank ?? "—"}</td>
      <td className="px-4 py-3 text-right">
        <RowActionsMenu>
          <RowActionsItem onClick={() => setEditOpen(true)}>Edit</RowActionsItem>
          {!c.hasActiveAssignment && <RowActionsItem onClick={() => setPlaceOpen(true)}>Place onto vessel/site</RowActionsItem>}
          <RowActionsSeparator />
          <RowActionsDestructiveItem onClick={() => setDeleteOpen(true)}>Delete</RowActionsDestructiveItem>
        </RowActionsMenu>
        <CrewFormButton ranks={ranks} editing={c} open={editOpen} onOpenChange={setEditOpen} />
        <PlaceDialog crew={c} ranks={ranks} vessels={vessels} sites={sites} open={placeOpen} onOpenChange={setPlaceOpen} />
        <DeleteConfirmDialog open={deleteOpen} onOpenChange={setDeleteOpen} label={c.name} onConfirm={() => deleteCrewMember(c.id)} />
      </td>
    </tr>
  );
}

function CrewFormButton({ ranks, editing, open, onOpenChange }: { ranks: RankOpt[]; editing?: Crew; open?: boolean; onOpenChange?: (v: boolean) => void }) {
  const router = useRouter();
  const [internalOpen, setInternalOpen] = useState(false);
  const isControlled = open !== undefined;
  const isOpen = isControlled ? open : internalOpen;
  const setOpen = isControlled ? (onOpenChange ?? (() => {})) : setInternalOpen;
  const [pending, setPending] = useState(false);
  const [error, setError] = useState("");
  const [f, setF] = useState({
    name: editing?.name ?? "", status: editing?.status ?? "CANDIDATE", type: editing?.type ?? "NEW", source: editing?.source ?? "CAREERS",
    email: editing?.email ?? "", phone: editing?.phone ?? "", appliedRankId: editing?.appliedRankId ?? "", currentRankId: editing?.currentRankId ?? "",
    experienceMonths: String(editing?.experienceMonths ?? 0),
  });

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    setPending(true); setError("");
    const fd = new FormData();
    if (editing) fd.set("id", editing.id);
    Object.entries(f).forEach(([k, v]) => v !== "" && fd.set(k, String(v)));
    const res = await (editing ? updateCrewMember(fd) : createCrewMember(fd));
    setPending(false);
    if ("error" in res) setError(res.error); else { setOpen(false); router.refresh(); }
  }

  return (
    <>
      {!isControlled && <button className={BTN} onClick={() => setOpen(true)}>+ Add crew</button>}
      <AdminDialog title={editing ? "Edit crew member" : "Add crew member"} open={isOpen} onClose={() => setOpen(false)}>
        <form onSubmit={submit} className="space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <input className={INPUT} placeholder="Name" value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} required />
            <select className={INPUT} value={f.status} onChange={(e) => setF({ ...f, status: e.target.value as CrewStatus })}>{STATUSES.map((s) => <option key={s} value={s}>{label(s)}</option>)}</select>
            <select className={INPUT} value={f.source} onChange={(e) => setF({ ...f, source: e.target.value as CandidateSource })}>{SOURCES.map((s) => <option key={s} value={s}>{label(s)}</option>)}</select>
            <label className="flex items-center gap-2 px-1 text-sm text-neutral-700">
              <input type="checkbox" className="h-4 w-4 rounded border-neutral-300 text-primary-600 focus:ring-primary-500/30" checked={f.type === "EX_HAND"} onChange={(e) => setF({ ...f, type: e.target.checked ? "EX_HAND" : "NEW" })} />
              Ex-hand (returning crew)
            </label>
            <select className={INPUT} value={f.appliedRankId} onChange={(e) => setF({ ...f, appliedRankId: e.target.value })}><option value="">Rank applied…</option>{ranks.map((r) => <option key={r.id} value={r.id}>{r.code} — {r.name}</option>)}</select>
            <select className={INPUT} value={f.currentRankId} onChange={(e) => setF({ ...f, currentRankId: e.target.value })}><option value="">Rank held…</option>{ranks.map((r) => <option key={r.id} value={r.id}>{r.code} — {r.name}</option>)}</select>
            <input className={INPUT} placeholder="Email" value={f.email} onChange={(e) => setF({ ...f, email: e.target.value })} />
            <input className={INPUT} placeholder="Phone" value={f.phone} onChange={(e) => setF({ ...f, phone: e.target.value })} />
            <input className={INPUT} type="number" min={0} placeholder="Experience (months)" value={f.experienceMonths} onChange={(e) => setF({ ...f, experienceMonths: e.target.value })} />
          </div>
          {error && <p className="text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>}
          <div className="flex justify-end gap-3 pt-1">
            <button type="button" className={SECONDARY} onClick={() => setOpen(false)}>Cancel</button>
            <button type="submit" disabled={pending || !f.name} className={BTN}>{pending ? "Saving…" : editing ? "Save changes" : "Add crew"}</button>
          </div>
        </form>
      </AdminDialog>
    </>
  );
}

function PlaceDialog({ crew, ranks, vessels, sites, open, onOpenChange }: { crew: Crew; ranks: RankOpt[]; vessels: Opt[]; sites: Opt[]; open: boolean; onOpenChange: (v: boolean) => void }) {
  const router = useRouter();
  const [pending, setPending] = useState(false);
  const [error, setError] = useState("");
  const [f, setF] = useState({ rankId: crew.currentRankId ?? crew.appliedRankId ?? "", location: "", signOnDate: "" });

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    setPending(true); setError("");
    const fd = new FormData();
    fd.set("crewMemberId", crew.id);
    fd.set("rankId", f.rankId);
    if (f.location.startsWith("v:")) fd.set("vesselId", f.location.slice(2));
    else if (f.location.startsWith("s:")) fd.set("siteId", f.location.slice(2));
    fd.set("signOnDate", f.signOnDate);
    const res = await placeCrew(fd);
    setPending(false);
    if ("error" in res) setError(res.error); else { onOpenChange(false); router.refresh(); }
  }

  return (
    <AdminDialog title={`Place ${crew.name}`} open={open} onClose={() => onOpenChange(false)}>
      <form onSubmit={submit} className="space-y-3">
        <p className="text-sm text-neutral-600">Assign this crew member directly to a vessel/site — no requisition needed. A candidate is promoted to active crew with an employee number.</p>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Rank *</label>
          <select className={INPUT} value={f.rankId} onChange={(e) => setF({ ...f, rankId: e.target.value })} required><option value="">— Rank —</option>{ranks.map((r) => <option key={r.id} value={r.id}>{r.code} — {r.name}</option>)}</select>
        </div>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Vessel / site *</label>
          <select className={INPUT} value={f.location} onChange={(e) => setF({ ...f, location: e.target.value })} required>
            <option value="">— Select —</option>
            {vessels.length > 0 && <optgroup label="Vessels">{vessels.map((v) => <option key={v.id} value={`v:${v.id}`}>{v.name}</option>)}</optgroup>}
            {sites.length > 0 && <optgroup label="Sites">{sites.map((s) => <option key={s.id} value={`s:${s.id}`}>{s.name}</option>)}</optgroup>}
          </select>
        </div>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Joining date *</label>
          <input type="date" className={INPUT} value={f.signOnDate} onChange={(e) => setF({ ...f, signOnDate: e.target.value })} required />
        </div>
        {error && <p className="text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>}
        <div className="flex justify-end gap-3 pt-1">
          <button type="button" className={SECONDARY} onClick={() => onOpenChange(false)}>Cancel</button>
          <button type="submit" disabled={pending || !f.rankId || !f.location || !f.signOnDate} className={BTN}>{pending ? "Placing…" : "Place crew"}</button>
        </div>
      </form>
    </AdminDialog>
  );
}
