"use client";

import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";

type ScanFile = { id: string; originalName: string; kind: string };

export type ScanOp = {
  id: string;
  sequence: number;
  name: string;
  status: string;
  qcRequired: boolean;
  instructions: string | null;
  materialNotes: string | null;
  settings: string | null;
  plannedMinutes: number | null;
  plannedUnits: number | null;
  unitsCompleted: number;
  claimedByUserId: string | null;
  claimedAt: string | null;
  machine: { id: string; name: string; kind: string } | null;
  part: {
    id: string;
    code: string;
    name: string;
    material: string | null;
    qty: number;
    stepFile: ScanFile | null;
    drawingFile: ScanFile | null;
    cutFile: ScanFile | null;
    thumbnailFileId: string | null;
    assembly: {
      id: string;
      code: string;
      name: string;
      qty: number;
      stepFile: ScanFile | null;
      drawingFile: ScanFile | null;
      cutFile: ScanFile | null;
      project: { id: string; code: string; name: string };
    };
  };
  claimedBy: { id: string; name: string } | null;
};

type Viewer = {
  id: string;
  role: "admin" | "operator";
  claimedByMe: boolean;
};

export default function ScanClient({ initialOp, viewer }: { initialOp: ScanOp; viewer: Viewer }) {
  const router = useRouter();
  const [op, setOp] = useState(initialOp);
  const [claimedByMe, setClaimedByMe] = useState(viewer.claimedByMe);
  const [error, setError] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();

  // Inline form state for pause/done. We keep one set of fields and let the
  // active button decide which API to hit — the fields (units processed, note)
  // are identical between release and close.
  const [units, setUnits] = useState("");
  const [note, setNote] = useState("");
  const [qcPassed, setQcPassed] = useState<null | boolean>(null);
  const [qcNotes, setQcNotes] = useState("");

  const isOperator = viewer.role === "operator";
  const active = op.status === "in_progress";
  const partial = op.status === "partial";
  const completed = op.status === "completed";

  // Total units the shop needs to run through this op to satisfy the project:
  //   assembly.qty (how many assemblies we're building) × part.qty (parts per
  //   assembly). This is distinct from plannedUnits, which is the admin's
  //   optional time estimate for a single run.
  const totalUnits = op.part.assembly.qty * op.part.qty;

  // Flat list of attached files (part first, then assembly). Rendered as big
  // tap targets so the operator can pull the drawing / STEP right from the
  // scan page without bouncing to the admin UI.
  const quickFiles: Array<{ label: string; file: ScanFile; scope: "part" | "assembly" }> = [];
  if (op.part.drawingFile) quickFiles.push({ label: "Drawing", file: op.part.drawingFile, scope: "part" });
  if (op.part.stepFile) quickFiles.push({ label: "3D / STEP", file: op.part.stepFile, scope: "part" });
  if (op.part.cutFile) quickFiles.push({ label: "Cut file", file: op.part.cutFile, scope: "part" });
  if (op.part.assembly.drawingFile)
    quickFiles.push({ label: "Assembly drawing", file: op.part.assembly.drawingFile, scope: "assembly" });
  if (op.part.assembly.stepFile)
    quickFiles.push({ label: "Assembly 3D", file: op.part.assembly.stepFile, scope: "assembly" });
  if (op.part.assembly.cutFile)
    quickFiles.push({ label: "Assembly cut", file: op.part.assembly.cutFile, scope: "assembly" });

  async function call(path: string, body?: unknown) {
    setError(null);
    const res = await fetch(path, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: body ? JSON.stringify(body) : undefined,
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError(data.error ?? "Request failed");
      return null;
    }
    return data;
  }

  function onClaim() {
    startTransition(async () => {
      const data = await call(`/api/v1/operations/${op.id}/claim`);
      if (data?.operation) {
        setOp({ ...op, ...data.operation });
        setClaimedByMe(true);
      }
    });
  }

  function onRelease() {
    startTransition(async () => {
      const data = await call(`/api/v1/operations/${op.id}/release`, {
        unitsProcessed: units ? Number(units) : undefined,
        note: note || undefined,
      });
      if (data?.operation) {
        setOp({ ...op, ...data.operation });
        setClaimedByMe(false);
        // Bounce back to /op so the operator sees their queue.
        router.push("/op");
      }
    });
  }

  function onClose() {
    if (op.qcRequired && qcPassed === null) {
      setError("This step requires QC — mark pass or fail before completing");
      return;
    }
    startTransition(async () => {
      const data = await call(`/api/v1/operations/${op.id}/close`, {
        unitsProcessed: units ? Number(units) : undefined,
        note: note || undefined,
        qc:
          qcPassed === null
            ? undefined
            : { passed: qcPassed, notes: qcNotes || undefined, measurements: "" },
      });
      if (data?.operation) {
        setOp({ ...op, ...data.operation });
        setClaimedByMe(false);
        router.push("/op");
      }
    });
  }

  return (
    <div className="space-y-4">
      <div className="rounded-2xl bg-white border border-slate-200 p-5 shadow-sm">
        <div className="text-xs text-slate-500">
          {op.part.assembly.project.code} · {op.part.assembly.code}
        </div>
        <h1 className="text-xl font-semibold mt-1">{op.part.name}</h1>
        <div className="text-slate-600 text-sm">
          Part <span className="font-mono">{op.part.code}</span>
          {op.part.material ? ` · ${op.part.material}` : null}
        </div>
        <div className="text-slate-700 text-sm mt-2">
          <span className="font-semibold text-slate-900">Total to produce: {totalUnits}</span>
          <span className="text-slate-500">
            {" "}({op.part.assembly.qty} assemblies × {op.part.qty} per assembly)
          </span>
          {op.unitsCompleted > 0 ? (
            <span className="ml-2 text-amber-700 font-medium">
              {op.unitsCompleted} done so far
            </span>
          ) : null}
        </div>

        <div className="mt-4 flex items-center gap-2 flex-wrap">
          <span className="inline-flex items-center rounded-full bg-slate-100 text-slate-700 text-xs px-2 py-1">
            Step {op.sequence}
          </span>
          <span
            className={`inline-flex items-center rounded-full text-xs px-2 py-1 ${
              completed
                ? "bg-emerald-100 text-emerald-800"
                : active
                  ? "bg-amber-100 text-amber-800"
                  : partial
                    ? "bg-orange-100 text-orange-800"
                    : "bg-slate-100 text-slate-700"
            }`}
          >
            {op.status === "in_progress"
              ? "in progress"
              : op.status === "partial"
                ? "partial"
                : op.status}
          </span>
          {op.qcRequired ? (
            <span className="inline-flex items-center rounded-full bg-purple-100 text-purple-800 text-xs px-2 py-1">
              QC
            </span>
          ) : null}
        </div>

        <div className="mt-3 text-lg">{op.name}</div>
        {op.machine ? (
          <div className="text-sm text-slate-600 mt-1">
            Machine: <span className="font-medium">{op.machine.name}</span>
            <span className="text-slate-400"> ({op.machine.kind})</span>
          </div>
        ) : null}
        {op.plannedMinutes || op.plannedUnits ? (
          <div className="text-sm text-slate-600 mt-1">
            Plan:
            {op.plannedMinutes ? ` ${op.plannedMinutes} min` : ""}
            {op.plannedMinutes && op.plannedUnits ? " ·" : ""}
            {op.plannedUnits ? ` ${op.plannedUnits} units` : ""}
          </div>
        ) : null}
      </div>

      {quickFiles.length > 0 ? (
        <div className="rounded-2xl bg-white border border-slate-200 p-5">
          <h2 className="text-sm font-semibold text-slate-900 mb-3">Quick files</h2>
          <div className="grid grid-cols-2 gap-2">
            {quickFiles.map(({ label, file, scope }) => (
              <a
                key={`${scope}-${file.id}`}
                href={`/api/v1/files/${file.id}/download`}
                target="_blank"
                rel="noopener"
                className="flex flex-col rounded-xl border border-slate-200 bg-slate-50 active:bg-slate-100 px-3 py-2 min-h-[64px]"
              >
                <span className="text-sm font-medium text-slate-900">{label}</span>
                <span className="text-[11px] text-slate-500 mt-0.5">
                  {scope === "assembly" ? "Assembly · " : "Part · "}
                  {file.kind.toUpperCase()}
                </span>
                <span className="text-[10px] text-slate-400 truncate mt-0.5" title={file.originalName}>
                  {file.originalName}
                </span>
              </a>
            ))}
          </div>
        </div>
      ) : null}

      {op.instructions ? (
        <div className="rounded-2xl bg-white border border-slate-200 p-5">
          <h2 className="text-sm font-semibold text-slate-900 mb-1">Instructions</h2>
          <p className="whitespace-pre-wrap text-sm text-slate-700">{op.instructions}</p>
        </div>
      ) : null}

      {op.materialNotes ? (
        <div className="rounded-2xl bg-white border border-slate-200 p-5">
          <h2 className="text-sm font-semibold text-slate-900 mb-1">Material notes</h2>
          <p className="whitespace-pre-wrap text-sm text-slate-700">{op.materialNotes}</p>
        </div>
      ) : null}

      {op.settings ? (
        <div className="rounded-2xl bg-white border border-slate-200 p-5">
          <h2 className="text-sm font-semibold text-slate-900 mb-1">Settings</h2>
          <pre className="text-xs bg-slate-50 border border-slate-200 rounded-md p-3 overflow-auto">
            {op.settings}
          </pre>
        </div>
      ) : null}

      {error ? (
        <div className="rounded-md bg-red-50 border border-red-200 text-red-700 text-sm px-3 py-2">
          {error}
        </div>
      ) : null}

      {isOperator && !completed ? (
        <div className="rounded-2xl bg-white border border-slate-200 p-5 space-y-4">
          {!claimedByMe && op.claimedBy && op.claimedByUserId !== viewer.id ? (
            <div className="rounded-md bg-amber-50 border border-amber-200 text-amber-900 text-sm px-3 py-2">
              <span className="font-medium">{op.claimedBy.name}</span> is currently on this step.
            </div>
          ) : null}

          {!claimedByMe ? (
            <button
              onClick={onClaim}
              disabled={isPending || (!!op.claimedByUserId && op.claimedByUserId !== viewer.id)}
              className="w-full h-14 rounded-xl bg-slate-900 text-white text-lg font-medium disabled:bg-slate-400"
            >
              {isPending
                ? partial
                  ? "Resuming…"
                  : "Claiming…"
                : partial
                  ? "Resume this step"
                  : "Start this step"}
            </button>
          ) : (
            <>
              <div className="grid grid-cols-1 gap-3">
                <label className="block">
                  <span className="text-sm font-medium text-slate-900">
                    Units processed
                    {op.unitsCompleted > 0 ? (
                      <span className="ml-2 text-xs text-slate-500 font-normal">
                        {op.unitsCompleted} of {totalUnits} already done
                      </span>
                    ) : null}
                  </span>
                  <input
                    type="number"
                    inputMode="numeric"
                    min={0}
                    value={units}
                    onChange={(e) => setUnits(e.target.value)}
                    placeholder={
                      op.unitsCompleted > 0
                        ? `${Math.max(0, totalUnits - op.unitsCompleted)} remaining`
                        : op.plannedUnits?.toString() ?? totalUnits.toString()
                    }
                    className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-base"
                  />
                </label>
                <label className="block">
                  <span className="text-sm font-medium text-slate-900">Note (optional)</span>
                  <textarea
                    value={note}
                    onChange={(e) => setNote(e.target.value)}
                    rows={2}
                    className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm"
                  />
                </label>
              </div>

              {op.qcRequired ? (
                <div className="rounded-md bg-purple-50 border border-purple-200 p-3 space-y-2">
                  <div className="text-sm font-medium text-purple-900">QC check (required)</div>
                  <div className="flex gap-2">
                    <button
                      type="button"
                      onClick={() => setQcPassed(true)}
                      className={`flex-1 h-10 rounded-md border text-sm font-medium ${
                        qcPassed === true
                          ? "bg-emerald-600 text-white border-emerald-700"
                          : "bg-white text-slate-700 border-slate-300"
                      }`}
                    >
                      Pass
                    </button>
                    <button
                      type="button"
                      onClick={() => setQcPassed(false)}
                      className={`flex-1 h-10 rounded-md border text-sm font-medium ${
                        qcPassed === false
                          ? "bg-red-600 text-white border-red-700"
                          : "bg-white text-slate-700 border-slate-300"
                      }`}
                    >
                      Fail
                    </button>
                  </div>
                  {qcPassed !== null ? (
                    <textarea
                      value={qcNotes}
                      onChange={(e) => setQcNotes(e.target.value)}
                      rows={2}
                      placeholder="QC notes"
                      className="w-full rounded-md border border-slate-300 px-3 py-2 text-sm"
                    />
                  ) : null}
                </div>
              ) : null}

              <div className="grid grid-cols-2 gap-3">
                <button
                  onClick={onRelease}
                  disabled={isPending}
                  className="h-14 rounded-xl bg-white border border-slate-300 text-slate-900 text-lg font-medium disabled:opacity-60"
                >
                  {isPending ? "…" : "Pause"}
                </button>
                <button
                  onClick={onClose}
                  disabled={isPending}
                  className="h-14 rounded-xl bg-emerald-600 text-white text-lg font-medium disabled:bg-emerald-400"
                >
                  {isPending ? "…" : "Done"}
                </button>
              </div>
            </>
          )}
        </div>
      ) : null}

      {completed ? (
        <div className="rounded-2xl bg-emerald-50 border border-emerald-200 p-5 text-center">
          <div className="text-emerald-900 font-semibold">Step completed</div>
          <div className="text-sm text-emerald-800 mt-1">Scan the next card or head back to your dashboard.</div>
        </div>
      ) : null}
    </div>
  );
}
