"use client";

import { useRef, useState } from "react";
import { useRouter } from "next/navigation";
import type { CandidateSource } from "@prisma/client";
import { AdminDialog } from "@/components/ui/admin-dialog";
import { addCandidate, updateCandidate } from "./actions";
import { FORM_SOURCE_OPTIONS, SOURCE_LABEL } from "./candidate-ui";

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";

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

export type EditableCandidate = {
  id: string;
  name: string;
  source: CandidateSource;
  appliedRankId: string | null;
  currentRankId: string | null;
  experienceMonths: number;
  vesselTypeExperience: string | null;
  email: string | null;
  phone: string | null;
  notes: string | null;
};

function CandidateFields({
  ranks,
  state,
  set,
  fileRef,
}: {
  ranks: RankOpt[];
  state: FieldState;
  set: <K extends keyof FieldState>(k: K, v: FieldState[K]) => void;
  fileRef: React.RefObject<HTMLInputElement | null>;
}) {
  return (
    <div className="space-y-3">
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Name *</label>
          <input className={INPUT} value={state.name} onChange={(e) => set("name", e.target.value)} required />
        </div>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Source</label>
          <select className={INPUT} value={state.source} onChange={(e) => set("source", e.target.value as CandidateSource)}>
            {FORM_SOURCE_OPTIONS.map((s) => (
              <option key={s} value={s}>{SOURCE_LABEL[s]}</option>
            ))}
          </select>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Rank applied for</label>
          <select className={INPUT} value={state.appliedRankId} onChange={(e) => set("appliedRankId", e.target.value)}>
            <option value="">—</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">Rank held</label>
          <select className={INPUT} value={state.currentRankId} onChange={(e) => set("currentRankId", e.target.value)}>
            <option value="">—</option>
            {ranks.map((r) => (
              <option key={r.id} value={r.id}>{r.code} — {r.name}</option>
            ))}
          </select>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Experience (months)</label>
          <input type="number" min={0} className={INPUT} value={state.experienceMonths} onChange={(e) => set("experienceMonths", e.target.value)} />
        </div>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Vessel type</label>
          <input className={INPUT} value={state.vesselTypeExperience} onChange={(e) => set("vesselTypeExperience", e.target.value)} placeholder="e.g. Dredger" />
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Email</label>
          <input type="email" className={INPUT} value={state.email} onChange={(e) => set("email", e.target.value)} />
        </div>
        <div>
          <label className="block text-xs font-medium text-neutral-700 mb-1">Phone</label>
          <input className={INPUT} value={state.phone} onChange={(e) => set("phone", e.target.value)} />
        </div>
      </div>

      <div>
        <label className="block text-xs font-medium text-neutral-700 mb-1">CV (PDF/DOC, optional)</label>
        <input ref={fileRef} type="file" accept=".pdf,.doc,.docx" className="block w-full text-sm text-neutral-600 file:mr-3 file:rounded-md file:border-0 file:bg-neutral-100 file:px-3 file:py-1.5 file:text-sm file:font-medium" />
      </div>

      <div>
        <label className="block text-xs font-medium text-neutral-700 mb-1">Notes</label>
        <input className={INPUT} value={state.notes} onChange={(e) => set("notes", e.target.value)} placeholder="Optional" />
      </div>
    </div>
  );
}

type FieldState = {
  name: string;
  source: CandidateSource;
  appliedRankId: string;
  currentRankId: string;
  experienceMonths: string;
  vesselTypeExperience: string;
  email: string;
  phone: string;
  notes: string;
};

function emptyState(): FieldState {
  return {
    name: "", source: "CAREERS", appliedRankId: "", currentRankId: "",
    experienceMonths: "0", vesselTypeExperience: "", email: "", phone: "", notes: "",
  };
}

function stateFrom(c: EditableCandidate): FieldState {
  return {
    name: c.name,
    // Ex-hand is an admin-only designation; the candidate form only edits origin.
    // Legacy rows may carry the EX_HAND source — show a sensible origin instead.
    source: c.source === "EX_HAND" ? "CAREERS" : c.source,
    appliedRankId: c.appliedRankId ?? "",
    currentRankId: c.currentRankId ?? "",
    experienceMonths: String(c.experienceMonths),
    vesselTypeExperience: c.vesselTypeExperience ?? "",
    email: c.email ?? "",
    phone: c.phone ?? "",
    notes: c.notes ?? "",
  };
}

function buildFormData(state: FieldState, file: File | undefined, id?: string): FormData {
  const fd = new FormData();
  if (id) fd.set("id", id);
  fd.set("name", state.name);
  fd.set("source", state.source);
  if (state.appliedRankId) fd.set("appliedRankId", state.appliedRankId);
  if (state.currentRankId) fd.set("currentRankId", state.currentRankId);
  fd.set("experienceMonths", state.experienceMonths || "0");
  if (state.vesselTypeExperience) fd.set("vesselTypeExperience", state.vesselTypeExperience);
  if (state.email) fd.set("email", state.email);
  if (state.phone) fd.set("phone", state.phone);
  if (state.notes) fd.set("notes", state.notes);
  if (file && file.size > 0) fd.set("cv", file);
  return fd;
}

export function AddCandidateButton({ ranks }: { ranks: RankOpt[] }) {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [pending, setPending] = useState(false);
  const [error, setError] = useState("");
  const [state, setState] = useState<FieldState>(emptyState);
  const fileRef = useRef<HTMLInputElement | null>(null);
  const set = <K extends keyof FieldState>(k: K, v: FieldState[K]) => setState((s) => ({ ...s, [k]: v }));

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setPending(true);
    setError("");
    const result = await addCandidate(buildFormData(state, fileRef.current?.files?.[0]));
    setPending(false);
    if ("error" in result) {
      setError(result.error);
    } else {
      setOpen(false);
      setState(emptyState());
      if (fileRef.current) fileRef.current.value = "";
      router.refresh();
    }
  }

  return (
    <>
      <button
        onClick={() => setOpen(true)}
        className="rounded-lg bg-primary-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-primary-700 transition-colors"
      >
        + Add candidate
      </button>
      <AdminDialog title="Add candidate" open={open} onClose={() => setOpen(false)}>
        <form onSubmit={handleSubmit} className="space-y-4">
          <CandidateFields ranks={ranks} state={state} set={set} fileRef={fileRef} />
          {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" onClick={() => setOpen(false)} className="rounded-lg border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50">Cancel</button>
            <button type="submit" disabled={pending} className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60">
              {pending ? "Adding…" : "Add candidate"}
            </button>
          </div>
        </form>
      </AdminDialog>
    </>
  );
}

export function EditCandidateButton({
  candidate,
  ranks,
  open,
  onOpenChange,
}: {
  candidate: EditableCandidate;
  ranks: RankOpt[];
  open: boolean;
  onOpenChange: (v: boolean) => void;
}) {
  const router = useRouter();
  const [pending, setPending] = useState(false);
  const [error, setError] = useState("");
  const [state, setState] = useState<FieldState>(() => stateFrom(candidate));
  const fileRef = useRef<HTMLInputElement | null>(null);
  const set = <K extends keyof FieldState>(k: K, v: FieldState[K]) => setState((s) => ({ ...s, [k]: v }));

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setPending(true);
    setError("");
    const result = await updateCandidate(buildFormData(state, fileRef.current?.files?.[0], candidate.id));
    setPending(false);
    if ("error" in result) {
      setError(result.error);
    } else {
      onOpenChange(false);
      router.refresh();
    }
  }

  return (
    <AdminDialog title="Edit candidate" open={open} onClose={() => onOpenChange(false)}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <CandidateFields ranks={ranks} state={state} set={set} fileRef={fileRef} />
        {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" onClick={() => onOpenChange(false)} className="rounded-lg border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50">Cancel</button>
          <button type="submit" disabled={pending} className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60">
            {pending ? "Saving…" : "Save changes"}
          </button>
        </div>
      </form>
    </AdminDialog>
  );
}
