import { useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  Search, Plus, Trash2, Loader2, Calendar, Users, Clock,
  CheckCircle2, Archive, AlertTriangle, PlayCircle, Eye
} from "lucide-react";
import { assignmentsService } from "@/services/assignments.service";
import { api } from "@/lib/api-client";
import { useBatches, useStudents } from "@/hooks/queries";
import { useToast } from "@/hooks/use-toast";
import type { ExamSchedule, ScheduleState, ExamScheduleCreateRequest } from "@/types";

interface CustomExam {
  id: number;
  title: string;
  status: string;
}

interface Entity {
  id: number;
  name: string;
}

const STATE_TABS: { key: ScheduleState | "all"; label: string; icon: React.ReactNode }[] = [
  { key: "all", label: "All", icon: <Eye className="h-3.5 w-3.5" /> },
  { key: "active", label: "Active", icon: <PlayCircle className="h-3.5 w-3.5" /> },
  { key: "planned", label: "Planned", icon: <Clock className="h-3.5 w-3.5" /> },
  { key: "past", label: "Past", icon: <CheckCircle2 className="h-3.5 w-3.5" /> },
  { key: "start_expired", label: "Start Expired", icon: <AlertTriangle className="h-3.5 w-3.5" /> },
  { key: "archived", label: "Archived", icon: <Archive className="h-3.5 w-3.5" /> },
];

const OPTION_FIELDS: { key: keyof ExamScheduleCreateRequest; label: string }[] = [
  { key: "full_length", label: "Full length exams" },
  { key: "generate_different", label: "Generate different exams" },
  { key: "auto_release_results", label: "Auto release results" },
  { key: "auto_start", label: "Auto start exam" },
  { key: "official_exam", label: "Official Exam" },
  { key: "hide_assignee_details", label: "Hide Assignees Details from Teachers" },
];

const stateBadgeVariant = (s: ScheduleState): "default" | "secondary" | "outline" | "destructive" => {
  switch (s) {
    case "active": return "default";
    case "planned": return "secondary";
    case "past": return "outline";
    case "start_expired": return "destructive";
    case "archived": return "outline";
    default: return "secondary";
  }
};

type FormState = {
  name: string;
  exam_id: string;
  entity_id: string;
  start_date: string;
  start_time: string;
  end_date: string;
  end_time: string;
  assign_mode: "entity" | "batch" | "individual";
  batch_ids: Set<number>;
  student_ids: Set<number>;
  full_length: boolean;
  generate_different: boolean;
  auto_release_results: boolean;
  auto_start: boolean;
  official_exam: boolean;
  hide_assignee_details: boolean;
};

const _iso = (d: Date) => {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
};

const emptyForm = (): FormState => {
  const today = new Date();
  const inOneWeek = new Date();
  inOneWeek.setDate(today.getDate() + 7);
  return {
    name: "",
    exam_id: "",
    entity_id: "",
    start_date: _iso(today),
    start_time: "09:00",
    end_date: _iso(inOneWeek),
    end_time: "17:00",
    assign_mode: "batch",
    batch_ids: new Set(),
    student_ids: new Set(),
    full_length: true,
    generate_different: false,
    auto_release_results: false,
    auto_start: false,
    official_exam: false,
    hide_assignee_details: false,
  };
};

export default function AssignmentsPage() {
  const [search, setSearch] = useState("");
  const [stateFilter, setStateFilter] = useState<ScheduleState | "all">("all");
  const [createOpen, setCreateOpen] = useState(false);
  const [form, setForm] = useState<FormState>(emptyForm());
  const [studentQuery, setStudentQuery] = useState("");
  const { toast } = useToast();
  const qc = useQueryClient();

  const schedulesQ = useQuery({
    queryKey: ["exam-schedules", stateFilter],
    queryFn: () => assignmentsService.listSchedules(
      stateFilter === "all" ? {} : { state: stateFilter }
    ),
  });
  const schedules = schedulesQ.data?.items ?? [];

  const customExamsQ = useQuery({
    queryKey: ["custom-exams-for-assign"],
    queryFn: () => api.get<{ items: CustomExam[]; total: number }>("/exam/custom/list?per_page=200"),
  });
  const publishedExams = (customExamsQ.data?.items ?? []).filter(
    (e) => e.status === "published" || e.status === "draft"
  );

  const entitiesQ = useQuery({
    queryKey: ["entities-for-assign"],
    queryFn: () => api.get<{ items: Entity[] }>("/entities"),
  });
  const entities = entitiesQ.data?.items ?? [];

  const batchesQ = useBatches({ size: 200 });
  const batches = batchesQ.data?.items ?? [];

  const studentsQ = useStudents({ size: 200 });
  const students = studentsQ.data?.items ?? [];
  const filteredStudents = useMemo(() => {
    const q = studentQuery.trim().toLowerCase();
    if (!q) return students;
    return students.filter((s) =>
      (s.name || "").toLowerCase().includes(q) ||
      (s.email || "").toLowerCase().includes(q),
    );
  }, [students, studentQuery]);

  const stateCounts = useMemo(() => {
    const all = schedulesQ.data?.items ?? [];
    const counts: Record<string, number> = { all: all.length };
    for (const s of all) {
      counts[s.state] = (counts[s.state] || 0) + 1;
    }
    return counts;
  }, [schedulesQ.data]);

  const allSchedulesQ = useQuery({
    queryKey: ["exam-schedules", "all"],
    queryFn: () => assignmentsService.listSchedules({}),
    enabled: stateFilter !== "all",
  });

  const totalCounts = useMemo(() => {
    const items = stateFilter === "all" ? schedules : (allSchedulesQ.data?.items ?? []);
    const counts: Record<string, number> = { all: items.length };
    for (const s of items) {
      counts[s.state] = (counts[s.state] || 0) + 1;
    }
    return counts;
  }, [stateFilter, schedules, allSchedulesQ.data]);

  const createMut = useMutation({
    mutationFn: (data: ExamScheduleCreateRequest) => assignmentsService.createSchedule(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["exam-schedules"] });
      setCreateOpen(false);
      setForm(emptyForm());
      toast({ title: "Exam scheduled successfully" });
    },
    onError: (err: Error) => toast({ variant: "destructive", title: "Error", description: err.message }),
  });

  const deleteMut = useMutation({
    mutationFn: (id: number) => assignmentsService.deleteSchedule(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["exam-schedules"] });
      toast({ title: "Schedule deleted" });
    },
    onError: (err: Error) => toast({ variant: "destructive", title: "Error", description: err.message }),
  });

  const archiveMut = useMutation({
    mutationFn: (id: number) => assignmentsService.archiveSchedule(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["exam-schedules"] });
      toast({ title: "Schedule archived" });
    },
  });

  const q = search.toLowerCase();
  const filtered = schedules.filter(
    (s) => s.name.toLowerCase().includes(q) || s.exam_title.toLowerCase().includes(q)
  );

  function handleCreate() {
    const startDt = form.start_date && form.start_time ? `${form.start_date}T${form.start_time}:00` : "";
    const endDt = form.end_date && form.end_time ? `${form.end_date}T${form.end_time}:00` : "";

    if (!form.name || !form.exam_id || !startDt || !endDt) {
      toast({ variant: "destructive", title: "Missing fields", description: "Please fill in name, exam, start date/time, and end date/time." });
      return;
    }

    createMut.mutate({
      name: form.name,
      exam_id: Number(form.exam_id),
      entity_id: form.entity_id ? Number(form.entity_id) : undefined,
      start_date: startDt,
      end_date: endDt,
      assign_mode: form.assign_mode,
      batch_ids: [...form.batch_ids],
      student_ids: [...form.student_ids],
      full_length: form.full_length,
      generate_different: form.generate_different,
      auto_release_results: form.auto_release_results,
      auto_start: form.auto_start,
      official_exam: form.official_exam,
      hide_assignee_details: form.hide_assignee_details,
    });
  }

  const updateF = (patch: Partial<FormState>) => setForm((p) => ({ ...p, ...patch }));

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold tracking-tight flex items-center gap-2">
            <Calendar className="h-6 w-6 text-primary" /> Assignments
          </h1>
          <p className="text-muted-foreground">Schedule exams and assign them to entities, classes, or students.</p>
        </div>
        <Button onClick={() => { setForm(emptyForm()); setCreateOpen(true); }}>
          <Plus className="h-4 w-4 mr-1" /> Schedule Exam
        </Button>
      </div>

      {/* State tabs */}
      <div className="inline-flex items-center rounded-full border-2 border-primary bg-primary/5 p-1 gap-0">
        {STATE_TABS.map((tab) => (
          <button
            key={tab.key}
            className={`flex items-center gap-1.5 px-4 py-2 rounded-full text-sm font-medium transition-all ${
              stateFilter === tab.key
                ? "bg-white text-primary shadow-sm"
                : "text-primary/70 hover:text-primary"
            }`}
            onClick={() => setStateFilter(tab.key)}
          >
            {tab.icon}
            {tab.label}
            <span className={`text-xs ml-0.5 ${stateFilter === tab.key ? "text-primary" : "text-primary/50"}`}>
              ({totalCounts[tab.key] ?? 0})
            </span>
          </button>
        ))}
      </div>

      <div className="relative max-w-sm">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <Input placeholder="Search schedules..." className="pl-9" value={search} onChange={(e) => setSearch(e.target.value)} />
      </div>

      {schedulesQ.isLoading ? (
        <div className="flex justify-center py-12"><Loader2 className="h-8 w-8 animate-spin text-muted-foreground" /></div>
      ) : filtered.length === 0 ? (
        <Card className="border-dashed">
          <CardContent className="p-12 text-center text-muted-foreground">
            <Calendar className="h-10 w-10 mx-auto mb-3 opacity-40" />
            <p className="font-medium">No exam schedules found</p>
            <p className="text-sm mt-1">Create a new schedule to assign exams to students.</p>
          </CardContent>
        </Card>
      ) : (
        <Card className="border-0 shadow-sm">
          <CardContent className="p-0">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Schedule Name</TableHead>
                  <TableHead>Exam</TableHead>
                  <TableHead>Entity</TableHead>
                  <TableHead>Start</TableHead>
                  <TableHead>End</TableHead>
                  <TableHead>State</TableHead>
                  <TableHead>Assignees</TableHead>
                  <TableHead>Completed</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {filtered.map((s) => (
                  <TableRow key={s.id}>
                    <TableCell className="font-medium">{s.name}</TableCell>
                    <TableCell>{s.exam_title}</TableCell>
                    <TableCell>{s.entity_name || "—"}</TableCell>
                    <TableCell className="text-xs">{s.start_date ? new Date(s.start_date).toLocaleString() : "—"}</TableCell>
                    <TableCell className="text-xs">{s.end_date ? new Date(s.end_date).toLocaleString() : "—"}</TableCell>
                    <TableCell>
                      <Badge variant={stateBadgeVariant(s.state)} className="capitalize">{s.state.replace("_", " ")}</Badge>
                    </TableCell>
                    <TableCell>
                      <div className="flex items-center gap-1"><Users className="h-3.5 w-3.5 text-muted-foreground" />{s.assignee_count}</div>
                    </TableCell>
                    <TableCell>{s.completed_count}</TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-1">
                        {s.state !== "archived" && (
                          <Button variant="ghost" size="icon" className="h-7 w-7" title="Archive"
                            onClick={() => archiveMut.mutate(s.id)}>
                            <Archive className="h-3.5 w-3.5" />
                          </Button>
                        )}
                        <Button variant="ghost" size="icon" className="h-7 w-7 text-destructive hover:text-destructive" title="Delete"
                          onClick={() => { if (confirm(`Delete schedule "${s.name}"?`)) deleteMut.mutate(s.id); }}>
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      )}

      {/* Create Schedule Dialog */}
      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Schedule Exam</DialogTitle>
            <DialogDescription>Select an exam, assign it to students, and set scheduling options.</DialogDescription>
          </DialogHeader>

          <div className="space-y-5 py-2">
            {/* Basic info */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Schedule Name <span className="text-destructive">*</span></Label>
                <Input value={form.name} onChange={(e) => updateF({ name: e.target.value })} placeholder="e.g. Q2 IELTS Exam" />
              </div>
              <div className="space-y-1">
                <Label>Select Exam <span className="text-destructive">*</span></Label>
                <Select value={form.exam_id} onValueChange={(v) => updateF({ exam_id: v })}>
                  <SelectTrigger><SelectValue placeholder="Choose exam..." /></SelectTrigger>
                  <SelectContent>
                    {publishedExams.map((e) => (
                      <SelectItem key={e.id} value={String(e.id)}>
                        {e.title} <span className="text-xs text-muted-foreground ml-1">({e.status})</span>
                      </SelectItem>
                    ))}
                    {publishedExams.length === 0 && (
                      <SelectItem value="_none" disabled>No exams available</SelectItem>
                    )}
                  </SelectContent>
                </Select>
              </div>
            </div>

            {/* Date/Time */}
            <div className="space-y-2">
              <Label className="text-sm font-semibold">Schedule Date & Time</Label>
              <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                <div className="space-y-1">
                  <Label className="text-xs">Start Date <span className="text-destructive">*</span></Label>
                  <Input type="date" value={form.start_date} onChange={(e) => updateF({ start_date: e.target.value })} />
                </div>
                <div className="space-y-1">
                  <Label className="text-xs">Start Time</Label>
                  <Input type="time" value={form.start_time} onChange={(e) => updateF({ start_time: e.target.value })} />
                </div>
                <div className="space-y-1">
                  <Label className="text-xs">End Date <span className="text-destructive">*</span></Label>
                  <Input type="date" value={form.end_date} onChange={(e) => updateF({ end_date: e.target.value })} />
                </div>
                <div className="space-y-1">
                  <Label className="text-xs">End Time</Label>
                  <Input type="time" value={form.end_time} onChange={(e) => updateF({ end_time: e.target.value })} />
                </div>
              </div>
            </div>

            {/* Options checkboxes */}
            <div className="space-y-2">
              <Label className="text-sm font-semibold">Exam Options</Label>
              <div className="flex flex-wrap gap-x-6 gap-y-2">
                {OPTION_FIELDS.map((opt) => (
                  <label key={opt.key} className="flex items-center gap-2 text-sm cursor-pointer">
                    <Checkbox
                      checked={form[opt.key] as boolean}
                      onCheckedChange={(checked) => updateF({ [opt.key]: !!checked } as Partial<FormState>)}
                      className="h-4 w-4"
                    />
                    {opt.label}
                  </label>
                ))}
              </div>
            </div>

            {/* Assignment target */}
            <div className="space-y-3">
              <Label className="text-sm font-semibold">Assign To</Label>
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div className="space-y-1">
                  <Label className="text-xs">Assignment Mode</Label>
                  <Select value={form.assign_mode} onValueChange={(v) => updateF({ assign_mode: v as FormState["assign_mode"] })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="entity">Entire Entity</SelectItem>
                      <SelectItem value="batch">Class / Batch</SelectItem>
                      <SelectItem value="individual">Individual Students</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div className="space-y-1">
                  <Label className="text-xs">Entity</Label>
                  <Select value={form.entity_id} onValueChange={(v) => updateF({ entity_id: v })}>
                    <SelectTrigger><SelectValue placeholder="Select entity..." /></SelectTrigger>
                    <SelectContent>
                      {entities.map((e) => (
                        <SelectItem key={e.id} value={String(e.id)}>{e.name}</SelectItem>
                      ))}
                      {entities.length === 0 && (
                        <SelectItem value="_none" disabled>No entities</SelectItem>
                      )}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {/* Batch selection */}
              {form.assign_mode === "batch" && (
                <div className="space-y-1">
                  <Label className="text-xs">Select Classes</Label>
                  <div className="max-h-36 overflow-y-auto border rounded-md p-2 space-y-1">
                    {batches.map((b) => (
                      <label key={b.id} className="flex items-center gap-2 text-sm cursor-pointer hover:bg-muted/50 rounded px-1 py-0.5">
                        <Checkbox
                          checked={form.batch_ids.has(b.id)}
                          onCheckedChange={(checked) => {
                            setForm((p) => {
                              const next = new Set(p.batch_ids);
                              checked ? next.add(b.id) : next.delete(b.id);
                              return { ...p, batch_ids: next };
                            });
                          }}
                          className="h-3.5 w-3.5"
                        />
                        {b.name}
                      </label>
                    ))}
                    {batches.length === 0 && <p className="text-xs text-muted-foreground italic text-center py-2">No classes available</p>}
                  </div>
                </div>
              )}

              {/* Individual student selection */}
              {form.assign_mode === "individual" && (
                <div className="space-y-1">
                  <div className="flex items-center justify-between gap-2">
                    <Label className="text-xs">Select Students</Label>
                    <span className="text-[11px] text-muted-foreground">
                      {form.student_ids.size} selected · {students.length} total
                    </span>
                  </div>
                  {/* Search box — needed because QA reported long student lists
                      made bottom entries unreachable inside the inner scroll
                      container. Filtering keeps the list short and predictable. */}
                  <Input
                    placeholder="Search students by name or email…"
                    value={studentQuery}
                    onChange={(e) => setStudentQuery(e.target.value)}
                    className="h-8 text-xs"
                  />
                  <div className="max-h-64 overflow-y-auto border rounded-md p-2 space-y-1">
                    {filteredStudents.map((s) => (
                      <label key={s.id} className="flex items-center gap-2 text-sm cursor-pointer hover:bg-muted/50 rounded px-1 py-0.5">
                        <Checkbox
                          checked={form.student_ids.has(s.id)}
                          onCheckedChange={(checked) => {
                            setForm((p) => {
                              const next = new Set(p.student_ids);
                              checked ? next.add(s.id) : next.delete(s.id);
                              return { ...p, student_ids: next };
                            });
                          }}
                          className="h-3.5 w-3.5"
                        />
                        {s.name}
                        {s.email && <span className="text-xs text-muted-foreground ml-auto">{s.email}</span>}
                      </label>
                    ))}
                    {filteredStudents.length === 0 && students.length > 0 && (
                      <p className="text-xs text-muted-foreground italic text-center py-2">
                        No students match “{studentQuery}”.
                      </p>
                    )}
                    {students.length === 0 && <p className="text-xs text-muted-foreground italic text-center py-2">No students available</p>}
                  </div>
                </div>
              )}
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>Cancel</Button>
            <Button disabled={createMut.isPending || !form.name || !form.exam_id || !form.start_date || !form.end_date} onClick={handleCreate}>
              {createMut.isPending ? <><Loader2 className="h-4 w-4 animate-spin mr-2" />Creating...</> : "Schedule Exam"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
