"use client";

import { useActionState, useEffect, useState } from "react";
import { useFormStatus } from "react-dom";
import { CheckCircle2, RefreshCw, ShieldAlert, Wand2 } from "lucide-react";
import { overrideCurriculumAction, reresolveCurriculumAction } from "@/app/actions/students";
import type { ActionResult } from "@/app/actions/shared";
import { buttonClass, Callout, Card, CardHeader, Field, inputClass, selectClass } from "@/components/ui";
import { useToast } from "@/components/toast";
import { AssignmentMethodBadge } from "@/components/status";
import type { Student } from "@/types";

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

interface CurriculumOption {
  id: string;
  code: string;
  name: string;
  status: string;
  total_program_units: number;
}

function PendingButton({ label, pendingLabel, icon }: { label: string; pendingLabel: string; icon: React.ReactNode }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className={buttonClass("primary", "sm")} disabled={pending}>
      {icon}
      {pending ? pendingLabel : label}
    </button>
  );
}

/**
 * Curriculum assignment (SPEC 12).
 *
 * Shows what the rule engine detected, and lets an authorised administrator
 * override it — never without a reason, and never silently.
 */
export function CurriculumAssignmentPanel({
  student,
  curricula,
  suggestion,
  canOverride,
  matchedRuleName,
}: {
  student: Student;
  curricula: CurriculumOption[];
  suggestion: {
    outcome: "MATCHED" | "UNRESOLVED" | "CONFLICT";
    message: string;
    curriculumId: string | null;
    matchedRuleName: string | null;
  };
  canOverride: boolean;
  matchedRuleName: string | null;
}) {
  const { toast } = useToast();
  const [overrideState, overrideAction] = useActionState<ActionResult, FormData>(
    overrideCurriculumAction,
    initialState,
  );
  const [resolveState, resolveAction] = useActionState<ActionResult, FormData>(
    reresolveCurriculumAction,
    initialState,
  );
  const [showForm, setShowForm] = useState(!student.curriculum_id);

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

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

  const current = curricula.find((c) => c.id === student.curriculum_id) ?? null;
  const suggested = suggestion.curriculumId ? curricula.find((c) => c.id === suggestion.curriculumId) : null;
  const assignable = curricula.filter((c) => c.status !== "ARCHIVED");

  return (
    <Card>
      <CardHeader title="Curriculum assignment" description="Resolved from the student number by the rule engine." />

      <div className="space-y-4 p-5">
        <div className="rounded-lg border border-ink-200 bg-ink-50 p-3">
          <p className="text-[11px] font-semibold uppercase tracking-wider text-ink-500">Currently assigned</p>
          {current ? (
            <>
              <p className="mt-1 text-sm font-semibold text-ink-900">{current.code}</p>
              <p className="text-[12px] leading-snug text-ink-600">{current.name}</p>
              <p className="tabular mt-1 text-[12px] text-ink-500">
                Total program units: <span className="font-semibold text-ink-700">{current.total_program_units}</span>
              </p>
            </>
          ) : (
            <p className="mt-1 text-sm font-medium text-amber-700">No curriculum assigned</p>
          )}
          <div className="mt-2 flex flex-wrap items-center gap-2">
            <AssignmentMethodBadge method={student.curriculum_assignment_method} />
            {matchedRuleName ? <span className="text-[11px] text-ink-500">via “{matchedRuleName}”</span> : null}
          </div>
          {student.curriculum_override_reason ? (
            <p className="mt-2 border-t border-ink-200 pt-2 text-[12px] leading-snug text-ink-600">
              <span className="font-medium text-ink-700">Override reason:</span> {student.curriculum_override_reason}
            </p>
          ) : null}
        </div>

        {/* What the resolver says right now */}
        {suggestion.outcome === "MATCHED" ? (
          <Callout tone={student.curriculum_id === suggestion.curriculumId ? "success" : "info"}>
            <span className="flex items-start gap-2">
              <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>
                Detected curriculum: <strong>{suggested?.code ?? "—"}</strong>
                <br />
                {suggestion.message}
              </span>
            </span>
          </Callout>
        ) : suggestion.outcome === "CONFLICT" ? (
          <Callout tone="danger" title="CURRICULUM_RULE_CONFLICT">
            <span className="flex items-start gap-2">
              <ShieldAlert className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>{suggestion.message}</span>
            </span>
          </Callout>
        ) : (
          <Callout tone="warning" title="CURRICULUM_UNRESOLVED">
            {suggestion.message} Assign the curriculum manually below, or add an assignment rule that covers this
            student-number pattern.
          </Callout>
        )}

        {/* Re-run the resolver — only useful while unassigned */}
        {canOverride && !student.curriculum_id && suggestion.outcome === "MATCHED" ? (
          <form action={resolveAction}>
            <input type="hidden" name="student_id" value={student.id} />
            <PendingButton
              label="Apply detected curriculum"
              pendingLabel="Applying…"
              icon={<Wand2 className="h-3.5 w-3.5" aria-hidden />}
            />
          </form>
        ) : null}

        {canOverride ? (
          showForm ? (
            <form action={overrideAction} className="space-y-3 border-t border-ink-200 pt-4">
              <input type="hidden" name="student_id" value={student.id} />
              <Field
                label="Assign curriculum"
                htmlFor="curriculum_id"
                required
                error={overrideState.fieldErrors?.curriculum_id}
              >
                <select
                  id="curriculum_id"
                  name="curriculum_id"
                  defaultValue={student.curriculum_id ?? suggestion.curriculumId ?? ""}
                  className={selectClass}
                  required
                >
                  <option value="">Select a curriculum…</option>
                  {assignable.map((curriculum) => (
                    <option key={curriculum.id} value={curriculum.id}>
                      {curriculum.code} — {curriculum.total_program_units} units
                      {curriculum.status !== "PUBLISHED" ? ` (${curriculum.status})` : ""}
                    </option>
                  ))}
                </select>
              </Field>

              <Field
                label="Reason for this assignment"
                htmlFor="reason"
                required
                error={overrideState.fieldErrors?.reason}
                hint="Recorded permanently in the audit trail alongside the automatic suggestion."
              >
                <textarea
                  id="reason"
                  name="reason"
                  rows={3}
                  minLength={10}
                  required
                  className={inputClass}
                  placeholder="e.g. Transferee admitted under the 2024 curriculum per Registrar memo 2026-014."
                />
              </Field>

              {student.curriculum_id ? (
                <Callout tone="warning">
                  Changing the curriculum clears this student&apos;s existing course assessments, because those rows
                  belong to the previous curriculum&apos;s requirements.
                </Callout>
              ) : null}

              <div className="flex flex-wrap gap-2">
                <PendingButton
                  label={student.curriculum_id ? "Override curriculum" : "Assign curriculum"}
                  pendingLabel="Saving…"
                  icon={<RefreshCw className="h-3.5 w-3.5" aria-hidden />}
                />
                {student.curriculum_id ? (
                  <button type="button" onClick={() => setShowForm(false)} className={buttonClass("ghost", "sm")}>
                    Cancel
                  </button>
                ) : null}
              </div>
            </form>
          ) : (
            <button type="button" onClick={() => setShowForm(true)} className={buttonClass("secondary", "sm", "w-full")}>
              <RefreshCw className="h-3.5 w-3.5" aria-hidden />
              Override curriculum assignment
            </button>
          )
        ) : (
          <p className="border-t border-ink-200 pt-3 text-[12px] text-ink-500">
            Your role cannot change curriculum assignment. Contact a Dean Administrator if this student is assigned to
            the wrong curriculum.
          </p>
        )}
      </div>
    </Card>
  );
}
