"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import type { CandidateSource, CandidateType, CrewStatus } from "@prisma/client";
import { Badge } from "@/components/ui/badge";
import { RowActionsMenu, RowActionsItem } from "@/components/ui/row-actions-menu";
import { AddCandidateButton, EditCandidateButton, type EditableCandidate } from "./candidate-form";
import { SOURCE_LABEL, SOURCE_OPTIONS, STATUS_LABEL, STATUS_VARIANT, experienceLabel } from "./candidate-ui";

type CandidateRow = {
  id: string;
  name: string;
  source: CandidateSource;
  type: CandidateType;
  status: CrewStatus;
  appliedRankId: string | null;
  appliedRank: string | null;
  currentRankId: string | null;
  currentRank: string | null;
  experienceMonths: number;
  vesselTypeExperience: string | null;
  email: string | null;
  phone: string | null;
  notes: string | null;
  hasCv: boolean;
};

type RankOpt = { id: string; code: string; name: string };

const INPUT =
  "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";

function Chip({ label, onClear }: { label: string; onClear: () => void }) {
  return (
    <span className="inline-flex items-center gap-1 rounded-full bg-primary-50 text-primary-700 px-2.5 py-1 text-xs font-medium">
      {label}
      <button onClick={onClear} className="text-primary-400 hover:text-primary-700" aria-label="Remove filter">✕</button>
    </span>
  );
}

function toEditable(c: CandidateRow): EditableCandidate {
  return {
    id: c.id, name: c.name, source: c.source,
    appliedRankId: c.appliedRankId, currentRankId: c.currentRankId,
    experienceMonths: c.experienceMonths, vesselTypeExperience: c.vesselTypeExperience,
    email: c.email, phone: c.phone, notes: c.notes,
  };
}

function CandidateRowView({ c, ranks }: { c: CandidateRow; ranks: RankOpt[] }) {
  const [editOpen, setEditOpen] = useState(false);
  return (
    <tr className="border-b border-neutral-100 last:border-0 hover:bg-neutral-50">
      <td className="px-4 py-3">
        <Link href={`/crewing/candidates/${c.id}`} className="font-medium text-neutral-900 hover:text-primary-700">{c.name}</Link>
        {c.type === "EX_HAND" && (
          <span className="ml-2 rounded-full bg-purple-100 text-purple-700 px-2 py-0.5 text-[10px] font-medium align-middle">Ex-hand</span>
        )}
        {c.hasCv && <span className="ml-2 text-xs text-neutral-400">CV</span>}
      </td>
      <td className="px-4 py-3 text-neutral-600 text-sm">{SOURCE_LABEL[c.source]}</td>
      <td className="px-4 py-3 text-neutral-600 text-sm">{c.currentRank ?? "—"}</td>
      <td className="px-4 py-3 text-neutral-600 text-sm">{c.appliedRank ?? "—"}</td>
      <td className="px-4 py-3 text-neutral-600 text-sm">{experienceLabel(c.experienceMonths)}</td>
      <td className="px-4 py-3"><Badge variant={STATUS_VARIANT[c.status]}>{STATUS_LABEL[c.status]}</Badge></td>
      <td className="px-4 py-3 text-right">
        <div onClick={(e) => e.stopPropagation()}>
          <RowActionsMenu>
            <RowActionsItem onClick={() => setEditOpen(true)}>Edit</RowActionsItem>
          </RowActionsMenu>
        </div>
        <EditCandidateButton candidate={toEditable(c)} ranks={ranks} open={editOpen} onOpenChange={setEditOpen} />
      </td>
    </tr>
  );
}

export function CandidatesManager({ candidates, ranks }: { candidates: CandidateRow[]; ranks: RankOpt[] }) {
  const [search, setSearch] = useState("");
  const [source, setSource] = useState<"ALL" | CandidateSource>("ALL");
  const [appliedRankId, setAppliedRankId] = useState("ALL");
  const [minExp, setMinExp] = useState("");

  const minExpMonths = minExp ? Math.max(0, parseInt(minExp, 10) || 0) : 0;

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return candidates.filter((c) => {
      if (source !== "ALL" && c.source !== source) return false;
      if (appliedRankId !== "ALL" && c.appliedRankId !== appliedRankId) return false;
      if (minExpMonths && c.experienceMonths < minExpMonths) return false;
      if (q && !`${c.name} ${c.appliedRank ?? ""} ${c.currentRank ?? ""}`.toLowerCase().includes(q)) return false;
      return true;
    });
  }, [candidates, search, source, appliedRankId, minExpMonths]);

  const rankName = (id: string) => ranks.find((r) => r.id === id)?.name ?? id;
  const hasFilters = Boolean(search) || source !== "ALL" || appliedRankId !== "ALL" || Boolean(minExp);
  const clearAll = () => { setSearch(""); setSource("ALL"); setAppliedRankId("ALL"); setMinExp(""); };

  return (
    <div>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold text-neutral-900">Candidates</h1>
          <p className="text-sm text-neutral-500 mt-0.5">
            {candidates.length} in the talent pool · careers applicants, ex-hands, walk-ins and referrals
          </p>
        </div>
        <AddCandidateButton ranks={ranks} />
      </div>

      {/* Filters */}
      <div className="mb-3 flex flex-wrap items-center gap-3">
        <input className={`${INPUT} flex-1 min-w-[200px]`} placeholder="Search name or rank…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <select className={INPUT} value={source} onChange={(e) => setSource(e.target.value as typeof source)}>
          <option value="ALL">All sources</option>
          {SOURCE_OPTIONS.map((s) => <option key={s} value={s}>{SOURCE_LABEL[s]}</option>)}
        </select>
        <select className={INPUT} value={appliedRankId} onChange={(e) => setAppliedRankId(e.target.value)}>
          <option value="ALL">Any rank applied</option>
          {ranks.map((r) => <option key={r.id} value={r.id}>{r.code} — {r.name}</option>)}
        </select>
        <input type="number" min={0} className={`${INPUT} w-40`} placeholder="Min exp (months)" value={minExp} onChange={(e) => setMinExp(e.target.value)} />
      </div>

      {/* Active filter chips + match count */}
      {hasFilters && (
        <div className="mb-4 flex flex-wrap items-center gap-2">
          {search && <Chip label={`“${search}”`} onClear={() => setSearch("")} />}
          {source !== "ALL" && <Chip label={`Source: ${SOURCE_LABEL[source]}`} onClear={() => setSource("ALL")} />}
          {appliedRankId !== "ALL" && <Chip label={`Rank: ${rankName(appliedRankId)}`} onClear={() => setAppliedRankId("ALL")} />}
          {minExp && <Chip label={`≥ ${minExp} mo`} onClear={() => setMinExp("")} />}
          <span className="text-xs text-neutral-500">{filtered.length} match{filtered.length === 1 ? "" : "es"}</span>
          <button onClick={clearAll} className="text-xs font-medium text-primary-600 hover:underline">Clear all</button>
        </div>
      )}

      <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">Source</th>
              <th className="px-4 py-3">Rank held</th>
              <th className="px-4 py-3">Rank applied</th>
              <th className="px-4 py-3">Experience</th>
              <th className="px-4 py-3">Status</th>
              <th className="px-4 py-3 w-12"></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 ? (
              <tr>
                <td colSpan={7} className="px-4 py-12 text-center text-neutral-400">
                  {candidates.length === 0 ? "No candidates yet. Add the first to the pool." : "No candidates match these filters."}
                </td>
              </tr>
            ) : (
              filtered.map((c) => <CandidateRowView key={c.id} c={c} ranks={ranks} />)
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
