import { useMemo, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Eye, Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Skeleton } from "@/components/ui/skeleton";
import { Separator } from "@/components/ui/separator";
import { useIeltsValidation, usePublishIeltsExam, useAssignIeltsExam } from "@/hooks/queries/useExamTemplates";
import { useStudents, useBatches } from "@/hooks/queries/useLms";
import { ieltsExamService } from "@/services/ielts-exam.service";
import type { ExamValidationReport, ValidationCheck } from "@/types";
import { toast } from "sonner";

function statusBadge(check: ValidationCheck) {
  if (check.status === "pass") {
    return <Badge className="bg-emerald-600 hover:bg-emerald-600">Pass</Badge>;
  }
  if (check.status === "fail") {
    return <Badge variant="destructive">Fail</Badge>;
  }
  return <Badge className="bg-amber-500 hover:bg-amber-500 text-foreground">Warning</Badge>;
}

export default function IeltsExamValidation() {
  const { examId: examIdParam } = useParams<{ examId: string }>();
  const navigate = useNavigate();
  const examId = Number(examIdParam);

  const validationQ = useIeltsValidation(Number.isFinite(examId) ? examId : 0);
  const publishMut = usePublishIeltsExam();
  const assignMut = useAssignIeltsExam();

  const [studentSearch, setStudentSearch] = useState("");
  const studentsQ = useStudents({ search: studentSearch || undefined, size: 200 });
  const batchesQ = useBatches();
  const [selectedStudents, setSelectedStudents] = useState<number[]>([]);
  const [selectedBatches, setSelectedBatches] = useState<number[]>([]);
  const [accessStart, setAccessStart] = useState("");
  const [accessEnd, setAccessEnd] = useState("");
  const [assignOpen, setAssignOpen] = useState(false);

  const report = useMemo((): ExamValidationReport | undefined => {
    const raw = validationQ.data as ExamValidationReport | { data?: ExamValidationReport } | undefined;
    if (!raw) return undefined;
    if ("checks" in raw && Array.isArray((raw as ExamValidationReport).checks)) {
      return raw as ExamValidationReport;
    }
    if ("data" in raw && raw.data && typeof raw.data === "object" && "checks" in raw.data) {
      return raw.data;
    }
    return undefined;
  }, [validationQ.data]);

  const checks: ValidationCheck[] = report?.checks ?? [];

  const allPass =
    report?.can_publish ?? (checks.length > 0 ? !checks.some((c) => c.status === "fail") : false);

  const toggleStudent = (id: number) => {
    setSelectedStudents((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
  };

  const toggleBatch = (id: number) => {
    setSelectedBatches((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
  };

  const saveDraft = async () => {
    try {
      await ieltsExamService.update(examId, { status: "draft" });
      toast.success("Saved as draft.");
    } catch {
      toast.error("Could not save draft.");
    }
  };

  const onPublish = async () => {
    try {
      await publishMut.mutateAsync(examId);
      toast.success("Exam published.");
    } catch {
      toast.error("Publish failed.");
    }
  };

  const onAssign = async () => {
    try {
      await assignMut.mutateAsync({
        examId,
        assignment: {
          student_ids: selectedStudents.length ? selectedStudents : undefined,
          batch_ids: selectedBatches.length ? selectedBatches : undefined,
          access_start: accessStart || undefined,
          access_end: accessEnd || undefined,
        },
      });
      toast.success("Assignment created.");
      setAssignOpen(false);
    } catch {
      toast.error("Assignment failed.");
    }
  };

  if (!Number.isFinite(examId) || examId <= 0) {
    return <p className="p-6 text-destructive">Invalid exam.</p>;
  }

  return (
    <div className="p-6 max-w-3xl mx-auto space-y-8">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Validate exam</h1>
          <p className="text-muted-foreground mt-1">Confirm structure, media, and scoring before go-live.</p>
        </div>
        <Button type="button" variant="outline" className="shrink-0 gap-2" onClick={() => navigate(`/admin/exam?preview=${examId}`)}>
          <Eye className="h-4 w-4" />
          Preview exam
        </Button>
      </div>

      {validationQ.isLoading ? (
        <div className="space-y-2">
          <Skeleton className="h-16 w-full" />
          <Skeleton className="h-16 w-full" />
        </div>
      ) : (
        <Card>
          <CardHeader>
            <CardTitle>Checklist</CardTitle>
            <CardDescription>Each rule must pass or be only a warning before publishing.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            {checks.length === 0 ? (
              <p className="text-sm text-muted-foreground">No validation results yet.</p>
            ) : (
              checks.map((c) => (
                <div key={c.name} className="rounded-lg border p-4 space-y-2">
                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <span className="font-medium">{c.name}</span>
                    {statusBadge(c)}
                  </div>
                  <p className="text-sm text-muted-foreground">{c.description}</p>
                  {c.details ? <p className="text-xs text-muted-foreground">{c.details}</p> : null}
                </div>
              ))
            )}
          </CardContent>
        </Card>
      )}

      <Separator />

      <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap">
        <Button type="button" variant="secondary" onClick={saveDraft}>
          Save as draft
        </Button>
        <Button type="button" disabled={!allPass || publishMut.isPending} onClick={onPublish}>
          {publishMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
          Publish
        </Button>

        <Dialog open={assignOpen} onOpenChange={setAssignOpen}>
          <DialogTrigger asChild>
            <Button type="button" variant="outline">
              Assign to students
            </Button>
          </DialogTrigger>
          <DialogContent className="max-w-lg">
            <DialogHeader>
              <DialogTitle>Assign exam</DialogTitle>
              <DialogDescription>Pick students or batches and an optional access window.</DialogDescription>
            </DialogHeader>
            <div className="space-y-4 py-2">
              <div className="space-y-2">
                <Label htmlFor="stu-search">Search students</Label>
                <Input
                  id="stu-search"
                  value={studentSearch}
                  onChange={(e) => setStudentSearch(e.target.value)}
                  placeholder="Name or email"
                />
              </div>
              <ScrollArea className="h-40 rounded-md border p-2">
                {(studentsQ.data?.items ?? studentsQ.data?.data ?? []).map((s) => (
                  <label key={s.id} className="flex items-center gap-2 py-1 text-sm cursor-pointer">
                    <Checkbox
                      checked={selectedStudents.includes(s.id)}
                      onCheckedChange={() => toggleStudent(s.id)}
                    />
                    <span>{s.name || s.email || `Student ${s.id}`}</span>
                  </label>
                ))}
                {(studentsQ.data?.items ?? studentsQ.data?.data ?? []).length === 0 ? (
                  <p className="text-sm text-muted-foreground p-2">No students found.</p>
                ) : null}
              </ScrollArea>
              <div className="space-y-2">
                <Label>Batches</Label>
                <ScrollArea className="h-28 rounded-md border p-2">
                  {(batchesQ.data?.items ?? batchesQ.data?.data ?? []).map((b) => (
                    <label key={b.id} className="flex items-center gap-2 py-1 text-sm cursor-pointer">
                      <Checkbox checked={selectedBatches.includes(b.id)} onCheckedChange={() => toggleBatch(b.id)} />
                      <span>{b.name}</span>
                    </label>
                  ))}
                </ScrollArea>
              </div>
              <div className="grid gap-3 sm:grid-cols-2">
                <div className="space-y-2">
                  <Label htmlFor="acc-start">Access start</Label>
                  <Input id="acc-start" type="datetime-local" value={accessStart} onChange={(e) => setAccessStart(e.target.value)} />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="acc-end">Access end</Label>
                  <Input id="acc-end" type="datetime-local" value={accessEnd} onChange={(e) => setAccessEnd(e.target.value)} />
                </div>
              </div>
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setAssignOpen(false)}>
                Cancel
              </Button>
              <Button type="button" disabled={assignMut.isPending} onClick={onAssign}>
                {assignMut.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                Confirm assign
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </div>
    </div>
  );
}
