"use client";

import * as React from "react";
import {
  Award,
  Sliders,
  Save,
  Download,
  FileSpreadsheet,
  CheckCircle2,
  Search,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Modal } from "@/components/ui/modal";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";

interface TeacherGradebookClientProps {
  teacherSubjects: any[];
  defaultTsId?: string;
}

export default function TeacherGradebookClient({
  teacherSubjects,
  defaultTsId,
}: TeacherGradebookClientProps) {
  const [selectedTSId, setSelectedTSId] = React.useState(
    defaultTsId && teacherSubjects.some((ts) => ts.id === defaultTsId)
      ? defaultTsId
      : teacherSubjects[0]?.id || ""
  );

  const currentTS = teacherSubjects.find((ts) => ts.id === selectedTSId);
  const students = currentTS?.class?.members?.map((m: any) => m.student) || [];

  // Weights State
  const [weightModalOpen, setWeightModalOpen] = React.useState(false);
  const [assignmentWeight, setAssignmentWeight] = React.useState("20");
  const [quizWeight, setQuizWeight] = React.useState("20");
  const [examWeight, setExamWeight] = React.useState("35");
  const [practiceWeight, setPracticeWeight] = React.useState("15");
  const [projectWeight, setProjectWeight] = React.useState("10");
  const [weightSaving, setWeightSaving] = React.useState(false);
  const [weightError, setWeightError] = React.useState("");

  // Grade Rows State
  const [gradeData, setGradeData] = React.useState<{ [studentId: string]: any }>({});
  const [isSaving, setIsSaving] = React.useState(false);
  const [search, setSearch] = React.useState("");

  // Populate existing weights & grades
  React.useEffect(() => {
    if (!currentTS) return;

    // Set weights if exist
    currentTS.gradeWeights?.forEach((w: any) => {
      if (w.category === "ASSIGNMENT") setAssignmentWeight(String(w.weightPercentage));
      else if (w.category === "QUIZ") setQuizWeight(String(w.weightPercentage));
      else if (w.category === "EXAM") setExamWeight(String(w.weightPercentage));
      else if (w.category === "PRACTICE") setPracticeWeight(String(w.weightPercentage));
      else if (w.category === "PROJECT") setProjectWeight(String(w.weightPercentage));
    });

    // Populate grades
    const gradesMap: any = {};
    currentTS.grades?.forEach((g: any) => {
      gradesMap[g.studentId] = {
        assignmentAvg: g.assignmentAvg,
        quizAvg: g.quizAvg,
        examAvg: g.examAvg,
        practiceAvg: g.practiceAvg,
        projectAvg: g.projectAvg,
        finalScore: g.finalScore,
        letterGrade: g.letterGrade,
        notes: g.notes || "",
      };
    });

    // Default missing students
    students.forEach((s: any) => {
      if (!gradesMap[s.id]) {
        gradesMap[s.id] = {
          assignmentAvg: 80,
          quizAvg: 80,
          examAvg: 80,
          practiceAvg: 80,
          projectAvg: 80,
          finalScore: 80,
          letterGrade: "B",
          notes: "",
        };
      }
    });

    setGradeData(gradesMap);
  }, [selectedTSId]);

  // Recalculate Final Score
  const calculateFinal = (studentId: string, overrides?: any) => {
    const row = { ...gradeData[studentId], ...overrides };
    const wAssign = parseFloat(assignmentWeight) || 0;
    const wQuiz = parseFloat(quizWeight) || 0;
    const wExam = parseFloat(examWeight) || 0;
    const wPractice = parseFloat(practiceWeight) || 0;
    const wProject = parseFloat(projectWeight) || 0;

    const assign = parseFloat(row.assignmentAvg) || 0;
    const quiz = parseFloat(row.quizAvg) || 0;
    const exam = parseFloat(row.examAvg) || 0;
    const practice = parseFloat(row.practiceAvg) || 0;
    const project = parseFloat(row.projectAvg) || 0;

    const final = parseFloat(
      (
        (assign * wAssign +
          quiz * wQuiz +
          exam * wExam +
          practice * wPractice +
          project * wProject) /
        100
      ).toFixed(1)
    );

    let letter = "A";
    if (final < 70) letter = "D";
    else if (final < 80) letter = "C";
    else if (final < 90) letter = "B";

    return { ...row, finalScore: final, letterGrade: letter };
  };

  const handleFieldChange = (studentId: string, field: string, value: string) => {
    const updated = calculateFinal(studentId, { [field]: value });
    setGradeData((prev) => ({
      ...prev,
      [studentId]: updated,
    }));
  };

  const handleSaveWeights = async (e: React.FormEvent) => {
    e.preventDefault();
    setWeightSaving(true);
    setWeightError("");

    const total =
      (parseFloat(assignmentWeight) || 0) +
      (parseFloat(quizWeight) || 0) +
      (parseFloat(examWeight) || 0) +
      (parseFloat(practiceWeight) || 0) +
      (parseFloat(projectWeight) || 0);

    if (Math.abs(total - 100) > 0.1) {
      setWeightError(`Total bobot harus tepat 100% (Saat ini: ${total}%).`);
      setWeightSaving(false);
      return;
    }

    try {
      const res = await fetch("/api/grades/weights", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          teacherSubjectId: selectedTSId,
          weights: [
            { category: "ASSIGNMENT", weightPercentage: parseFloat(assignmentWeight) },
            { category: "QUIZ", weightPercentage: parseFloat(quizWeight) },
            { category: "EXAM", weightPercentage: parseFloat(examWeight) },
            { category: "PRACTICE", weightPercentage: parseFloat(practiceWeight) },
            { category: "PROJECT", weightPercentage: parseFloat(projectWeight) },
          ],
        }),
      });

      const data = await res.json();
      setWeightSaving(false);
      if (res.ok && data.success) {
        setWeightModalOpen(false);
        // Recalculate all students with new weights
        const recomputed: any = {};
        students.forEach((s: any) => {
          recomputed[s.id] = calculateFinal(s.id);
        });
        setGradeData(recomputed);
      } else {
        setWeightError(data.error || "Gagal menyimpan bobot.");
      }
    } catch (err) {
      setWeightSaving(false);
      setWeightError("Terjadi gangguan jaringan.");
    }
  };

  const handleSaveAllGrades = async () => {
    setIsSaving(true);

    const entries = students.map((s: any) => ({
      studentId: s.id,
      assignmentAvg: gradeData[s.id]?.assignmentAvg || 0,
      quizAvg: gradeData[s.id]?.quizAvg || 0,
      examAvg: gradeData[s.id]?.examAvg || 0,
      practiceAvg: gradeData[s.id]?.practiceAvg || 0,
      projectAvg: gradeData[s.id]?.projectAvg || 0,
      finalScore: gradeData[s.id]?.finalScore || 0,
      letterGrade: gradeData[s.id]?.letterGrade || "B",
      notes: gradeData[s.id]?.notes || "",
    }));

    try {
      const res = await fetch("/api/grades/calculate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          teacherSubjectId: selectedTSId,
          gradeEntries: entries,
        }),
      });

      const data = await res.json();
      setIsSaving(false);
      if (res.ok && data.success) {
        alert("Buku nilai berhasil disimpan!");
      } else {
        alert(data.error || "Gagal menyimpan nilai.");
      }
    } catch (err) {
      setIsSaving(false);
      alert("Terjadi gangguan jaringan.");
    }
  };

  const filteredStudents = students.filter(
    (s: any) =>
      s.fullName.toLowerCase().includes(search.toLowerCase()) ||
      s.nis.includes(search)
  );

  return (
    <div className="space-y-6">
      {/* Top Filter and Actions */}
      <div className="flex flex-col sm:flex-row items-center justify-between gap-4">
        <div className="flex flex-wrap items-center gap-2 w-full sm:w-auto">
          <Select
            value={selectedTSId}
            onChange={(e) => setSelectedTSId(e.target.value)}
            className="w-full sm:w-64"
          >
            {teacherSubjects.map((ts) => (
              <option key={ts.id} value={ts.id}>
                {ts.subject.name} - Kelas {ts.class.name}
              </option>
            ))}
          </Select>

          <Button
            size="sm"
            variant="outline"
            onClick={() => setWeightModalOpen(true)}
            className="text-xs font-bold"
          >
            <Sliders className="mr-1.5 h-3.5 w-3.5 text-blue-600" />
            Atur Bobot Penilaian
          </Button>
        </div>

        <div className="flex items-center gap-2 w-full sm:w-auto justify-end">
          <a
            href={`/api/grades/export?teacherSubjectId=${selectedTSId}`}
            download
          >
            <Button size="sm" variant="outline" className="text-xs">
              <Download className="mr-1.5 h-3.5 w-3.5" />
              Ekspor CSV
            </Button>
          </a>

          <Button
            size="sm"
            onClick={handleSaveAllGrades}
            isLoading={isSaving}
            className="text-xs font-bold shadow-sm"
          >
            <Save className="mr-1.5 h-3.5 w-3.5" />
            Simpan Buku Nilai
          </Button>
        </div>
      </div>

      {/* Active Weights Summary Pill */}
      <div className="p-3 rounded-2xl bg-blue-50/70 border border-blue-200/80 flex flex-wrap items-center justify-between gap-3 text-xs text-blue-950 font-semibold">
        <span className="flex items-center gap-1.5 font-bold">
          <Award className="h-4 w-4 text-blue-600" />
          Bobot Aktif:
        </span>
        <div className="flex flex-wrap gap-2 text-[11px]">
          <span className="px-2 py-0.5 rounded-lg bg-white border border-blue-200">
            Tugas: {assignmentWeight}%
          </span>
          <span className="px-2 py-0.5 rounded-lg bg-white border border-blue-200">
            Kuis: {quizWeight}%
          </span>
          <span className="px-2 py-0.5 rounded-lg bg-white border border-blue-200">
            Ujian ASTS/ASAS: {examWeight}%
          </span>
          <span className="px-2 py-0.5 rounded-lg bg-white border border-blue-200">
            Praktik: {practiceWeight}%
          </span>
          <span className="px-2 py-0.5 rounded-lg bg-white border border-blue-200">
            Proyek: {projectWeight}%
          </span>
        </div>
      </div>

      {/* Gradebook Spreadsheet-like Table */}
      <Card>
        <CardHeader className="pb-3 border-b border-slate-100 flex flex-row items-center justify-between">
          <CardTitle>
            Lembar Buku Nilai: {currentTS?.subject?.name} (Kelas {currentTS?.class?.name})
          </CardTitle>
          <div className="relative w-56">
            <Search className="absolute left-2.5 top-2.5 h-3.5 w-3.5 text-slate-400" />
            <input
              type="text"
              placeholder="Cari siswa..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full pl-8 pr-2.5 py-1.5 rounded-lg border border-slate-200 text-xs bg-white text-slate-800 placeholder:text-slate-400 focus:outline-none focus:ring-1 focus:ring-blue-500"
            />
          </div>
        </CardHeader>

        <CardContent className="p-0">
          <div className="overflow-x-auto">
            <table className="w-full text-xs text-left">
              <thead className="bg-slate-50 text-slate-600 font-bold border-b border-slate-200">
                <tr>
                  <th className="py-3 px-3">No</th>
                  <th className="py-3 px-3">NIS</th>
                  <th className="py-3 px-3">Nama Lengkap Siswa</th>
                  <th className="py-3 px-2 text-center w-20">Tugas ({assignmentWeight}%)</th>
                  <th className="py-3 px-2 text-center w-20">Kuis ({quizWeight}%)</th>
                  <th className="py-3 px-2 text-center w-20">Ujian ({examWeight}%)</th>
                  <th className="py-3 px-2 text-center w-20">Praktik ({practiceWeight}%)</th>
                  <th className="py-3 px-2 text-center w-20">Proyek ({projectWeight}%)</th>
                  <th className="py-3 px-3 text-center bg-blue-50 text-blue-900 font-black">Nilai Akhir</th>
                  <th className="py-3 px-2 text-center bg-blue-50 text-blue-900">Predikat</th>
                  <th className="py-3 px-3">Catatan Pembelajaran</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {filteredStudents.map((s: any, idx: number) => {
                  const data = gradeData[s.id] || {};

                  return (
                    <tr key={s.id} className="hover:bg-slate-50/80 transition-colors">
                      <td className="py-2.5 px-3 text-slate-400 font-mono">{idx + 1}</td>
                      <td className="py-2.5 px-3 font-mono font-semibold text-slate-700">
                        {s.nis}
                      </td>
                      <td className="py-2.5 px-3 font-bold text-slate-900 whitespace-nowrap">
                        {s.fullName}
                      </td>

                      {/* Inputs for categories */}
                      <td className="py-2 px-1 text-center">
                        <input
                          type="number"
                          step="0.5"
                          min="0"
                          max="100"
                          value={data.assignmentAvg ?? 80}
                          onChange={(e) => handleFieldChange(s.id, "assignmentAvg", e.target.value)}
                          className="w-16 text-center font-semibold text-xs py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>

                      <td className="py-2 px-1 text-center">
                        <input
                          type="number"
                          step="0.5"
                          min="0"
                          max="100"
                          value={data.quizAvg ?? 80}
                          onChange={(e) => handleFieldChange(s.id, "quizAvg", e.target.value)}
                          className="w-16 text-center font-semibold text-xs py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>

                      <td className="py-2 px-1 text-center">
                        <input
                          type="number"
                          step="0.5"
                          min="0"
                          max="100"
                          value={data.examAvg ?? 80}
                          onChange={(e) => handleFieldChange(s.id, "examAvg", e.target.value)}
                          className="w-16 text-center font-semibold text-xs py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>

                      <td className="py-2 px-1 text-center">
                        <input
                          type="number"
                          step="0.5"
                          min="0"
                          max="100"
                          value={data.practiceAvg ?? 80}
                          onChange={(e) => handleFieldChange(s.id, "practiceAvg", e.target.value)}
                          className="w-16 text-center font-semibold text-xs py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>

                      <td className="py-2 px-1 text-center">
                        <input
                          type="number"
                          step="0.5"
                          min="0"
                          max="100"
                          value={data.projectAvg ?? 80}
                          onChange={(e) => handleFieldChange(s.id, "projectAvg", e.target.value)}
                          className="w-16 text-center font-semibold text-xs py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>

                      {/* Calculated Final Score */}
                      <td className="py-2.5 px-3 text-center bg-blue-50/50 font-black text-sm text-blue-700">
                        {data.finalScore ?? 80}
                      </td>

                      <td className="py-2.5 px-2 text-center bg-blue-50/50">
                        <span
                          className={`font-bold px-2 py-0.5 rounded text-xs ${
                            data.letterGrade === "A"
                              ? "bg-emerald-100 text-emerald-800"
                              : data.letterGrade === "B"
                              ? "bg-blue-100 text-blue-800"
                              : "bg-amber-100 text-amber-800"
                          }`}
                        >
                          {data.letterGrade ?? "B"}
                        </span>
                      </td>

                      <td className="py-2 px-2">
                        <input
                          type="text"
                          placeholder="Catatan kompetensi siswa..."
                          value={data.notes || ""}
                          onChange={(e) => handleFieldChange(s.id, "notes", e.target.value)}
                          className="w-full text-xs px-2 py-1 rounded border border-slate-200 focus:border-blue-500 focus:outline-none"
                        />
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </CardContent>
      </Card>

      {/* Modal Atur Bobot Penilaian */}
      <Modal
        isOpen={weightModalOpen}
        onClose={() => setWeightModalOpen(false)}
        title="Konfigurasi Bobot Penilaian Dinamis"
        description="Atur persentase bobot masing-masing kategori. Total wajib tepat 100%."
        maxWidth="md"
      >
        <form onSubmit={handleSaveWeights} className="space-y-4">
          {weightError && (
            <div className="p-3 rounded-lg bg-rose-50 border border-rose-200 text-rose-700 text-xs">
              {weightError}
            </div>
          )}

          <div className="space-y-3">
            <div className="flex items-center justify-between gap-4">
              <span className="text-xs font-semibold text-slate-700">
                1. Tugas Pembelajaran (%):
              </span>
              <Input
                type="number"
                min="0"
                max="100"
                value={assignmentWeight}
                onChange={(e) => setAssignmentWeight(e.target.value)}
                className="w-24 text-center font-bold"
                required
              />
            </div>

            <div className="flex items-center justify-between gap-4">
              <span className="text-xs font-semibold text-slate-700">
                2. Kuis Formatif (%):
              </span>
              <Input
                type="number"
                min="0"
                max="100"
                value={quizWeight}
                onChange={(e) => setQuizWeight(e.target.value)}
                className="w-24 text-center font-bold"
                required
              />
            </div>

            <div className="flex items-center justify-between gap-4">
              <span className="text-xs font-semibold text-slate-700">
                3. Ujian ASTS / Sumatif (%):
              </span>
              <Input
                type="number"
                min="0"
                max="100"
                value={examWeight}
                onChange={(e) => setExamWeight(e.target.value)}
                className="w-24 text-center font-bold"
                required
              />
            </div>

            <div className="flex items-center justify-between gap-4">
              <span className="text-xs font-semibold text-slate-700">
                4. Praktik Laboratorium (%):
              </span>
              <Input
                type="number"
                min="0"
                max="100"
                value={practiceWeight}
                onChange={(e) => setPracticeWeight(e.target.value)}
                className="w-24 text-center font-bold"
                required
              />
            </div>

            <div className="flex items-center justify-between gap-4">
              <span className="text-xs font-semibold text-slate-700">
                5. Proyek Profil Pelajar (P5) (%):
              </span>
              <Input
                type="number"
                min="0"
                max="100"
                value={projectWeight}
                onChange={(e) => setProjectWeight(e.target.value)}
                className="w-24 text-center font-bold"
                required
              />
            </div>
          </div>

          {/* Real-time total counter */}
          <div className="p-3 rounded-xl bg-slate-50 border border-slate-200 flex justify-between items-center text-xs font-bold">
            <span>Total Persentase:</span>
            <span
              className={
                (parseFloat(assignmentWeight) || 0) +
                  (parseFloat(quizWeight) || 0) +
                  (parseFloat(examWeight) || 0) +
                  (parseFloat(practiceWeight) || 0) +
                  (parseFloat(projectWeight) || 0) ===
                100
                  ? "text-emerald-600 font-mono"
                  : "text-rose-600 font-mono"
              }
            >
              {(parseFloat(assignmentWeight) || 0) +
                (parseFloat(quizWeight) || 0) +
                (parseFloat(examWeight) || 0) +
                (parseFloat(practiceWeight) || 0) +
                (parseFloat(projectWeight) || 0)}
              % (Wajib 100%)
            </span>
          </div>

          <div className="flex justify-end gap-2.5 pt-3 border-t border-slate-100">
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => setWeightModalOpen(false)}
            >
              Batal
            </Button>
            <Button type="submit" size="sm" isLoading={weightSaving}>
              Terapkan Bobot
            </Button>
          </div>
        </form>
      </Modal>
    </div>
  );
}
