"use client";

import Link from "next/link";
import { useMemo, useRef } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { useAlertConfirm } from "@/components/ui/alert-dialog";
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import {
  TTB_MAX_DOC_BYTES,
  TTB_STEPS,
  TTB_STORAGE_KEY,
  countCompleted,
  getStepStatus,
  type TtbStep,
  type TtbStepDocument,
  type TtbStepStatus,
  type TtbStepStatusValue,
} from "@/lib/compliance/ttb-steps";
import { logActivity } from "@/lib/activity/log";

// ──────────────────────────────────────────────────────────────────────────
// Display config
// ──────────────────────────────────────────────────────────────────────────

const STATUS_OPTIONS: TtbStepStatusValue[] = [
  "not_started",
  "in_progress",
  "submitted",
  "approved",
  "blocked",
];

const STATUS_LABEL: Record<TtbStepStatusValue, string> = {
  not_started: "Not started",
  in_progress: "In progress",
  submitted: "Submitted",
  approved: "Approved",
  blocked: "Blocked",
};

const STATUS_TONE: Record<
  TtbStepStatusValue,
  "outline" | "warning" | "info" | "success" | "destructive"
> = {
  not_started: "outline",
  in_progress: "warning",
  submitted: "info",
  approved: "success",
  blocked: "destructive",
};

const KOSHU_SLUG = "koshu-sake";

// ──────────────────────────────────────────────────────────────────────────
// Helpers
// ──────────────────────────────────────────────────────────────────────────

function nowIso(): string {
  return new Date().toISOString();
}

function formatBytes(bytes: number | undefined): string {
  if (bytes == null || !Number.isFinite(bytes)) return "—";
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
}

function readFileAsBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result;
      if (typeof result === "string") {
        resolve(result);
      } else {
        reject(new Error("Could not read file as data URL"));
      }
    };
    reader.onerror = () => reject(reader.error ?? new Error("File read error"));
    reader.readAsDataURL(file);
  });
}

// ──────────────────────────────────────────────────────────────────────────
// Main component
// ──────────────────────────────────────────────────────────────────────────

export function TtbChecklist() {
  const [statuses, setStatuses] = useLocalStorage<TtbStepStatus[]>(
    TTB_STORAGE_KEY,
    []
  );
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  const koshu = useMemo(
    () => ALL_ORGANIZATIONS.find((o) => o.slug === KOSHU_SLUG),
    []
  );

  const statusByNumber = useMemo(() => {
    const m: Record<number, TtbStepStatus> = {};
    for (const s of statuses) m[s.number] = s;
    return m;
  }, [statuses]);

  const completed = countCompleted(statuses);
  const total = TTB_STEPS.length;
  const pct = total > 0 ? Math.round((completed / total) * 100) : 0;

  function upsertStatus(stepNumber: number, patch: Partial<TtbStepStatus>) {
    setStatuses((prev) => {
      const existing = prev.find((s) => s.number === stepNumber);
      const base: TtbStepStatus =
        existing ?? {
          number: stepNumber,
          status: "not_started",
          notes: "",
          documents: [],
          updatedAt: "",
        };
      const next: TtbStepStatus = {
        ...base,
        ...patch,
        number: stepNumber,
        updatedAt: nowIso(),
      };
      if (existing) {
        return prev.map((s) => (s.number === stepNumber ? next : s));
      }
      return [...prev, next];
    });
  }

  function setStatus(stepNumber: number, status: TtbStepStatusValue) {
    const prior = statusByNumber[stepNumber]?.status;
    upsertStatus(stepNumber, { status });
    if (prior === status) return;
    try {
      const step = TTB_STEPS.find((s) => s.number === stepNumber);
      const stepLabel = step ? `Step ${step.number}: ${step.title}` : `Step ${stepNumber}`;
      const verb =
        status === "submitted"
          ? "submitted"
          : status === "approved"
            ? "approved"
            : "updated";
      const title =
        status === "submitted"
          ? `Submitted TTB ${stepLabel}`
          : status === "approved"
            ? `Approved TTB ${stepLabel}`
            : `Updated TTB ${stepLabel} → ${STATUS_LABEL[status]}`;
      logActivity({
        source: "ttb",
        verb,
        title,
        entitySlug: KOSHU_SLUG,
        href: "/app/compliance/koshu-sake/ttb",
        meta: { stepNumber, status },
      });
    } catch {
      // fire-and-forget
    }
  }

  function setNotes(stepNumber: number, notes: string) {
    upsertStatus(stepNumber, { notes });
  }

  function addDocument(stepNumber: number, doc: TtbStepDocument) {
    const current = getStepStatus(statuses, stepNumber);
    upsertStatus(stepNumber, { documents: [...current.documents, doc] });
  }

  function removeDocument(stepNumber: number, index: number) {
    const current = getStepStatus(statuses, stepNumber);
    const next = current.documents.filter((_, i) => i !== index);
    upsertStatus(stepNumber, { documents: next });
  }

  async function resetAll() {
    const ok = await confirmAlert({
      title: "Reset every step to Not started?",
      description: "Notes and uploaded documents will be cleared. Cannot be undone.",
      actionLabel: "Reset all",
      destructive: true,
    });
    if (!ok) return;
    setStatuses([]);
  }

  return (
    <>
    <div className="space-y-6">
      <Link
        href="/app/compliance"
        className="text-sm text-muted-foreground hover:text-foreground inline-block"
      >
        ← All compliance
      </Link>

      {/* ─── Header card ────────────────────────────────────────────── */}
      <Card className="border-[var(--sag-brand)]/30 bg-[var(--sag-brand)]/5">
        <CardContent className="p-6">
          <div className="flex items-start justify-between gap-4 flex-wrap">
            <div className="min-w-0">
              <div className="flex items-center gap-2 flex-wrap mb-1">
                <span className="text-3xl" aria-hidden>
                  {koshu?.emoji ?? "🍶"}
                </span>
                {koshu && (
                  <Badge
                    variant={koshu.status === "Active" ? "success" : "outline"}
                  >
                    {koshu.status}
                  </Badge>
                )}
                <Badge variant="outline" className="text-[10px]">
                  {koshu?.entityType ?? "C-Corp"}
                </Badge>
                <span className="text-xs text-muted-foreground">
                  TTB Federal Basic Permit (Wine Producer)
                </span>
              </div>
              <h2 className="text-2xl font-semibold">
                {koshu?.name ?? "Koshu Aged American Sake"} — TTB winery permit
              </h2>
              <p className="text-sm text-muted-foreground mt-1 max-w-2xl">
                Sake is classified federally as <strong>wine</strong> under 26
                USC § 5041. Track the 12 canonical steps of the TTB winery
                permit process below, attach documents, and capture notes for
                each filing.
              </p>
              <p className="text-xs text-muted-foreground mt-2 italic">
                Verify each step against current TTB guidance. Engage a
                TTB-experienced attorney before filing.
              </p>
            </div>
            <div className="flex flex-col items-end gap-3 shrink-0">
              <div className="text-right">
                <div className="section-label">
                  Progress
                </div>
                <div className="text-2xl font-semibold tabular-nums">
                  {pct}%
                </div>
                <div className="text-xs text-muted-foreground tabular-nums">
                  {completed} of {total} steps submitted or approved
                </div>
              </div>
              <div className="flex gap-2">
                <Button variant="outline" size="sm" asChild>
                  <a
                    href="https://www.ttbonline.gov"
                    target="_blank"
                    rel="noopener noreferrer"
                  >
                    Open PONL ↗
                  </a>
                </Button>
                <Button variant="ghost" size="sm" onClick={resetAll}>
                  Mark all as not-started
                </Button>
              </div>
            </div>
          </div>
          <div className="mt-5">
            <Progress value={pct} />
          </div>
        </CardContent>
      </Card>

      {/* ─── Step cards ─────────────────────────────────────────────── */}
      <div className="space-y-3">
        {TTB_STEPS.map((step) => (
          <StepCard
            key={step.number}
            step={step}
            state={
              statusByNumber[step.number] ?? {
                number: step.number,
                status: "not_started",
                notes: "",
                documents: [],
                updatedAt: "",
              }
            }
            onStatusChange={(s) => setStatus(step.number, s)}
            onNotesBlur={(n) => setNotes(step.number, n)}
            onAddDocument={(d) => addDocument(step.number, d)}
            onRemoveDocument={(i) => removeDocument(step.number, i)}
          />
        ))}
      </div>

      <p className="text-xs text-muted-foreground">
        This checklist tracks the canonical 12-step TTB winery permit process.
        The Compliance Agent can reference each step by number — say &quot;tell
        me about step 7&quot; to get a deeper write-up. Checklist state saved
        locally in this browser under{" "}
        <code className="font-mono">{TTB_STORAGE_KEY}</code>.
      </p>
    </div>
    <AlertConfirmPortal />
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Step card
// ──────────────────────────────────────────────────────────────────────────

function StepCard({
  step,
  state,
  onStatusChange,
  onNotesBlur,
  onAddDocument,
  onRemoveDocument,
}: {
  step: TtbStep;
  state: TtbStepStatus;
  onStatusChange: (status: TtbStepStatusValue) => void;
  onNotesBlur: (notes: string) => void;
  onAddDocument: (doc: TtbStepDocument) => void;
  onRemoveDocument: (index: number) => void;
}) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const isDone = state.status === "submitted" || state.status === "approved";
  const isBlocked = state.status === "blocked";
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const files = e.target.files;
    if (!files || files.length === 0) return;
    const file = files[0];

    if (file.size > TTB_MAX_DOC_BYTES) {
      const proceed = await confirmAlert({
        title: "Attach this oversized file?",
        description: `"${file.name}" is ${formatBytes(file.size)} (max ${formatBytes(
          TTB_MAX_DOC_BYTES
        )}). LocalStorage can't hold large files reliably — attach anyway?`,
        actionLabel: "Attach anyway",
      });
      if (!proceed) {
        if (fileInputRef.current) fileInputRef.current.value = "";
        return;
      }
    }

    try {
      const inlineData = await readFileAsBase64(file);
      onAddDocument({
        name: file.name,
        size: file.size,
        mimeType: file.type || undefined,
        uploadedAt: nowIso(),
        inlineData,
      });
    } catch {
      alert(`Could not attach ${file.name}.`);
    } finally {
      if (fileInputRef.current) fileInputRef.current.value = "";
    }
  }

  return (
    <>
    <Card
      className={
        isDone
          ? "border-green-500/30"
          : isBlocked
            ? "border-destructive/40"
            : undefined
      }
    >
      <CardContent className="p-5">
        <div className="flex items-start gap-4">
          {/* Step number bubble */}
          <div
            className={`w-10 h-10 rounded-full border-2 flex items-center justify-center font-mono text-sm font-semibold shrink-0 ${
              isDone
                ? "border-green-500 bg-green-500/10 text-green-700"
                : isBlocked
                  ? "border-destructive bg-destructive/10 text-destructive"
                  : "border-muted-foreground/20 text-foreground"
            }`}
            aria-label={`Step ${step.number}`}
          >
            {state.status === "approved"
              ? "✓"
              : isBlocked
                ? "!"
                : step.number}
          </div>

          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2 flex-wrap">
              <h3 className="text-base font-semibold">
                Step {step.number}. {step.title}
              </h3>
              <Badge
                variant={STATUS_TONE[state.status]}
                className="text-[10px]"
              >
                {STATUS_LABEL[state.status]}
              </Badge>
              <span className="text-xs text-muted-foreground tabular-nums">
                ~{step.estimatedDurationDays} days
              </span>
            </div>

            <p className="mt-2 text-sm text-foreground/85">{step.summary}</p>

            {step.requiredDocs.length > 0 && (
              <div className="mt-3">
                <div className="section-label mb-1">
                  Required documents
                </div>
                <ul className="list-disc list-inside text-xs text-foreground/80 space-y-0.5">
                  {step.requiredDocs.map((doc) => (
                    <li key={doc}>{doc}</li>
                  ))}
                </ul>
              </div>
            )}

            {step.externalLinks.length > 0 && (
              <div className="mt-3 flex items-center gap-3 flex-wrap text-xs">
                {step.externalLinks.map((link) => (
                  <a
                    key={link.href}
                    href={link.href}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-[var(--sag-brand)] underline hover:opacity-80"
                  >
                    {link.label} ↗
                  </a>
                ))}
              </div>
            )}

            {/* ─── Controls ─────────────────────────────────────── */}
            <div className="mt-4 grid gap-3 md:grid-cols-[auto_1fr]">
              <div className="flex items-center gap-2 flex-wrap">
                <label className="section-label">
                  Status
                </label>
                <select
                  value={state.status}
                  onChange={(e) =>
                    onStatusChange(e.target.value as TtbStepStatusValue)
                  }
                  className="h-9 rounded-md border border-input bg-background px-2 text-xs"
                  aria-label={`Status for step ${step.number}`}
                >
                  {STATUS_OPTIONS.map((opt) => (
                    <option key={opt} value={opt}>
                      {STATUS_LABEL[opt]}
                    </option>
                  ))}
                </select>
              </div>

              <div>
                <label
                  htmlFor={`notes-${step.number}`}
                  className="section-label"
                >
                  Notes
                </label>
                <textarea
                  id={`notes-${step.number}`}
                  defaultValue={state.notes}
                  onBlur={(e) => {
                    if (e.target.value !== state.notes) {
                      onNotesBlur(e.target.value);
                    }
                  }}
                  rows={2}
                  className="mt-1 w-full text-xs rounded-md border border-input bg-background p-2"
                  placeholder="Filing number, contact at TTB, outstanding questions, etc."
                />
              </div>
            </div>

            {/* ─── Documents ────────────────────────────────────── */}
            <div className="mt-4">
              <div className="flex items-center justify-between gap-2 flex-wrap">
                <div className="section-label">
                  Attached documents
                </div>
                <div>
                  <input
                    ref={fileInputRef}
                    id={`file-${step.number}`}
                    type="file"
                    className="hidden"
                    onChange={handleFileChange}
                  />
                  <label
                    htmlFor={`file-${step.number}`}
                    className="inline-flex items-center h-8 px-3 rounded-md border border-input bg-background text-xs cursor-pointer hover:bg-accent"
                  >
                    + Upload doc
                  </label>
                </div>
              </div>
              {state.documents.length === 0 ? (
                <p className="mt-2 text-xs text-muted-foreground italic">
                  No documents attached.
                </p>
              ) : (
                <ul className="mt-2 flex flex-wrap gap-2">
                  {state.documents.map((doc, i) => (
                    <li
                      key={`${doc.name}-${doc.uploadedAt}-${i}`}
                      className="inline-flex items-center gap-2 rounded-full border border-input bg-muted/40 pl-3 pr-1 py-1 text-xs"
                    >
                      <span className="font-medium truncate max-w-[200px]">
                        {doc.name}
                      </span>
                      <span className="text-muted-foreground tabular-nums">
                        {formatBytes(doc.size)}
                      </span>
                      <button
                        type="button"
                        onClick={() => onRemoveDocument(i)}
                        className="h-6 w-6 inline-flex items-center justify-center rounded-full hover:bg-destructive/10 hover:text-destructive"
                        aria-label={`Remove ${doc.name}`}
                      >
                        ×
                      </button>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        </div>
      </CardContent>
    </Card>
    <AlertConfirmPortal />
    </>
  );
}
