"use client";

import { useActionState, useEffect, useState } from "react";
import { useFormStatus } from "react-dom";
import { useRouter } from "next/navigation";
import { Archive, BadgeCheck, TriangleAlert } from "lucide-react";
import { archiveCurriculumAction, publishCurriculumAction } from "@/app/actions/curricula";
import type { ActionResult } from "@/app/actions/shared";
import { buttonClass, Callout, Card, CardHeader } from "@/components/ui";
import { useToast } from "@/components/toast";
import type { CurriculumStatus } from "@/types";

const initial: ActionResult = { ok: false, message: null };

function Submit({ label, pendingLabel, variant = "primary" }: { label: string; pendingLabel: string; variant?: "primary" | "danger" }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className={buttonClass(variant, "sm", "w-full")} disabled={pending}>
      {variant === "primary" ? <BadgeCheck className="h-3.5 w-3.5" aria-hidden /> : <Archive className="h-3.5 w-3.5" aria-hidden />}
      {pending ? pendingLabel : label}
    </button>
  );
}

/** Curriculum publication with explicit acknowledgement of source issues (SPEC 11, 53). */
export function PublishPanel({
  curriculumId,
  code,
  status,
  totalUnits,
  blockers,
  unacknowledgedCount,
  studentCount,
  canPublish,
  canArchive,
}: {
  curriculumId: string;
  code: string;
  status: CurriculumStatus;
  totalUnits: number;
  blockers: { code: string; message: string }[];
  unacknowledgedCount: number;
  studentCount: number;
  canPublish: boolean;
  canArchive: boolean;
}) {
  const router = useRouter();
  const { toast } = useToast();
  const [publishState, publishAction] = useActionState<ActionResult, FormData>(publishCurriculumAction, initial);
  const [archiveState, archiveAction] = useActionState<ActionResult, FormData>(archiveCurriculumAction, initial);
  const [acknowledged, setAcknowledged] = useState(false);
  const [confirmArchive, setConfirmArchive] = useState(false);

  useEffect(() => {
    if (publishState.message) {
      toast({ tone: publishState.ok ? "success" : "error", title: publishState.message });
      if (publishState.ok) router.refresh();
    }
  }, [publishState, toast, router]);

  useEffect(() => {
    if (archiveState.message) {
      toast({ tone: archiveState.ok ? "success" : "error", title: archiveState.message });
      if (archiveState.ok) {
        setConfirmArchive(false);
        router.refresh();
      }
    }
  }, [archiveState, toast, router]);

  return (
    <Card>
      <CardHeader title="Publication" description="A curriculum should be published before it is used for official assessment." />
      <div className="space-y-3 p-5">
        {status === "PUBLISHED" ? (
          <Callout tone="success" title={`${code} is published`}>
            {studentCount} student{studentCount === 1 ? " is" : "s are"} assigned to it, using {totalUnits} total
            program units as the denominator.
          </Callout>
        ) : status === "ARCHIVED" ? (
          <Callout tone="info" title={`${code} is archived`}>
            Archived curricula cannot be assigned to students.
          </Callout>
        ) : (
          <>
            {blockers.length > 0 ? (
              <Callout tone="danger" title="Publication is blocked">
                <ul className="mt-1 list-disc space-y-1 pl-4">
                  {blockers.map((blocker) => (
                    <li key={blocker.code}>{blocker.message}</li>
                  ))}
                </ul>
              </Callout>
            ) : (
              <Callout tone="info">
                Ready to publish with <strong>{totalUnits}</strong> total program units.
              </Callout>
            )}

            {canPublish ? (
              <form action={publishAction} className="space-y-3">
                <input type="hidden" name="curriculum_id" value={curriculumId} />
                {unacknowledgedCount > 0 ? (
                  <label className="flex items-start gap-2.5 rounded-lg border border-amber-100 bg-amber-50 p-3">
                    <input
                      type="checkbox"
                      name="acknowledge"
                      checked={acknowledged}
                      onChange={(event) => setAcknowledged(event.target.checked)}
                      className="mt-0.5 h-4 w-4 rounded border-amber-300 text-brand-600 focus:ring-brand-500"
                    />
                    <span className="text-[12px] leading-relaxed text-amber-800">
                      <span className="flex items-center gap-1.5 font-semibold">
                        <TriangleAlert className="h-3.5 w-3.5" aria-hidden />
                        Acknowledge {unacknowledgedCount} source-file issue(s)
                      </span>
                      I have reviewed the validation report and accept these discrepancies. Acknowledgement is recorded
                      in the audit trail and does not delete the validation history.
                    </span>
                  </label>
                ) : null}
                <fieldset disabled={blockers.length > 0 || (unacknowledgedCount > 0 && !acknowledged)}>
                  <Submit label={`Publish ${code}`} pendingLabel="Publishing…" />
                </fieldset>
              </form>
            ) : (
              <p className="text-[12px] text-ink-500">Your role cannot publish curricula.</p>
            )}
          </>
        )}

        {canArchive && status !== "ARCHIVED" ? (
          <div className="border-t border-ink-200 pt-3">
            {confirmArchive ? (
              <form action={archiveAction} className="space-y-2">
                <input type="hidden" name="curriculum_id" value={curriculumId} />
                <p className="text-[12px] leading-relaxed text-ink-600">
                  Archive {code}? It will no longer be assignable to students. Existing assignments are unaffected.
                </p>
                <div className="flex gap-2">
                  <Submit label="Confirm archive" pendingLabel="Archiving…" variant="danger" />
                  <button type="button" onClick={() => setConfirmArchive(false)} className={buttonClass("ghost", "sm")}>
                    Cancel
                  </button>
                </div>
              </form>
            ) : (
              <button type="button" onClick={() => setConfirmArchive(true)} className={buttonClass("ghost", "sm", "w-full")}>
                <Archive className="h-3.5 w-3.5" aria-hidden />
                Archive curriculum
              </button>
            )}
          </div>
        ) : null}
      </div>
    </Card>
  );
}
