"use client";

import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useMemo, useState } from "react";
import { CountdownTimer } from "@/components/academic/CountdownTimer";
import { ListExportActions } from "@/components/export/ListExportActions";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input, Select } from "@/components/ui/Field";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { ApiError, apiGet, apiPost, getAcademicYearId } from "@/lib/api";
import { isTeacherRole } from "@/lib/permissions";
import { KIND_LABELS, reportCardWorkspaceHref } from "@/lib/report-cards";

interface WorkspaceSubject {
  class_subject_id: number;
  subject_id: number;
  subject_name?: string | null;
  subject_code?: string | null;
}

interface WorkspacePeriod {
  id: number;
  name: string;
  kind?: string | null;
  entered?: number;
  grade_entry_ends_at?: string | null;
}

interface WorkspaceStudent {
  id: number;
  student_code?: string | null;
  national_code?: string | null;
  first_name?: string | null;
  last_name?: string | null;
  father_name?: string | null;
  score?: number | string | null;
  descriptive_grade?: string | null;
  teacher_comment?: string | null;
}

interface WorkspacePayload {
  class_room: {
    id: number;
    name: string;
    branch_name?: string | null;
    grade_level_name?: string | null;
    evaluation_mode?: string | null;
  };
  subjects: WorkspaceSubject[];
  periods: WorkspacePeriod[];
  selected_subject_id?: number | null;
  selected_period_id?: number | null;
  window_open: boolean;
  students: WorkspaceStudent[];
  summary: { total: number; entered: number };
}

interface ClassOption {
  id: number;
  name: string;
  pending_tasks?: Array<{ report_card_id: number; subject_id: number; period_id: number }>;
}

type RowState = { score: string; descriptive_grade: string; teacher_comment: string };

export function ReportCardGradesPanel({ cardId }: { cardId: number }) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const canEnterGrades = isTeacherRole();
  const [classes, setClasses] = useState<ClassOption[]>([]);
  const classId = searchParams.get("class_id") ?? "";
  const initialSubject = searchParams.get("subject_id") ?? "";
  const initialPeriod = searchParams.get("period_id") ?? "";
  const [data, setData] = useState<WorkspacePayload | null>(null);
  const [subjectId, setSubjectId] = useState(initialSubject);
  const [periodId, setPeriodId] = useState(initialPeriod);
  const [rows, setRows] = useState<Record<number, RowState>>({});
  const [repeatScore, setRepeatScore] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);

  const inputsDisabled =
    !canEnterGrades || data?.window_open === false;

  const replaceQuery = useCallback(
    (nextClass: string, sid: string, pid: string) => {
      router.replace(
        reportCardWorkspaceHref(cardId, "grades", {
          class_id: nextClass || undefined,
          subject_id: sid || undefined,
          period_id: pid || undefined,
        }),
      );
    },
    [cardId, router],
  );

  useEffect(() => {
    (async () => {
      try {
        const yearId = getAcademicYearId();
        if (canEnterGrades) {
          const list = await apiGet<ClassOption[]>(
            `/grade-entries/teacher-classes${yearId ? `?academic_year_id=${yearId}` : ""}`,
          );
          const mine = list.filter((row) =>
            (row.pending_tasks ?? []).some((task) => task.report_card_id === cardId),
          );
          setClasses(mine.length ? mine : list);
        } else {
          setClasses(await apiGet<ClassOption[]>("/class-rooms"));
        }
      } catch (err) {
        setError(err instanceof ApiError ? err.message : "خطا در بارگذاری کلاس‌ها");
      }
    })();
  }, [cardId, canEnterGrades]);

  useEffect(() => {
    if (classId || !classes[0]) return;
    const first = classes[0];
    const task = first.pending_tasks?.find((item) => item.report_card_id === cardId);
    replaceQuery(String(first.id), initialSubject || String(task?.subject_id ?? ""), initialPeriod || String(task?.period_id ?? ""));
  }, [classes, classId, cardId, initialSubject, initialPeriod, replaceQuery]);

  const load = useCallback(async () => {
    if (!classId) return;
    setError(null);
    setLoading(true);
    try {
      const params = new URLSearchParams({
        class_room_id: classId,
        report_card_id: String(cardId),
      });
      const yearId = getAcademicYearId();
      if (yearId) params.set("academic_year_id", String(yearId));
      if (initialSubject) params.set("subject_id", initialSubject);
      if (initialPeriod) params.set("report_card_period_id", initialPeriod);
      const payload = await apiGet<WorkspacePayload>(
        `/grade-entries/teacher-workspace?${params.toString()}`,
      );
      setData(payload);
      const resolvedSubject = String(payload.selected_subject_id || payload.subjects[0]?.subject_id || "");
      const resolvedPeriod = String(payload.selected_period_id || payload.periods[0]?.id || "");
      setSubjectId(resolvedSubject);
      setPeriodId(resolvedPeriod);
      const nextRows: Record<number, RowState> = {};
      for (const student of payload.students) {
        nextRows[student.id] = {
          score: student.score != null ? String(student.score) : "",
          descriptive_grade: student.descriptive_grade ?? "",
          teacher_comment: student.teacher_comment ?? "",
        };
      }
      setRows(nextRows);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
    } finally {
      setLoading(false);
    }
  }, [classId, cardId, initialSubject, initialPeriod]);

  useEffect(() => {
    void load();
  }, [load]);

  const selectedPeriod = useMemo(
    () => data?.periods.find((p) => String(p.id) === periodId) ?? null,
    [data, periodId],
  );
  const isDescriptive =
    selectedPeriod?.kind === "official" && data?.class_room.evaluation_mode === "descriptive";

  const save = async () => {
    if (!canEnterGrades || !periodId || !subjectId || !data) return;
    setSaving(true);
    setError(null);
    setSuccess(null);
    const entries = data.students.map((student) => ({
      enrollment_id: student.id,
      subject_id: Number(subjectId),
      score: isDescriptive || rows[student.id]?.score === "" ? null : Number(rows[student.id]?.score),
      descriptive_grade: rows[student.id]?.descriptive_grade || null,
      teacher_comment: rows[student.id]?.teacher_comment || null,
      score_type: isDescriptive ? "descriptive" : "numeric",
    }));
    try {
      await apiPost("/grade-entries/bulk", {
        report_card_period_id: Number(periodId),
        entries,
      });
      setSuccess("نمرات ثبت شد.");
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ذخیره نمرات");
    } finally {
      setSaving(false);
    }
  };

  if (!classId && !classes.length && loading) {
    return <PageContentSkeleton rows={6} />;
  }

  return (
    <div className="space-y-3">
      {error ? <Alert tone="error">{error}</Alert> : null}
      {success ? <Alert tone="success">{success}</Alert> : null}
      {data && !data.window_open ? (
        <Alert tone="warning">پنجره ثبت نمره این دوره بسته است.</Alert>
      ) : null}

      <div className="grid gap-3 md:grid-cols-3">
        <Field label="کلاس">
          <Select
            value={classId}
            onChange={(e) => replaceQuery(e.target.value, subjectId, periodId)}
          >
            <option value="">انتخاب کلاس</option>
            {classes.map((item) => (
              <option key={item.id} value={item.id}>{item.name}</option>
            ))}
          </Select>
        </Field>
        <Field label="درس">
          <Select
            value={subjectId}
            onChange={(e) => replaceQuery(classId, e.target.value, periodId)}
          >
            {(data?.subjects ?? []).map((subject) => (
              <option key={subject.subject_id} value={subject.subject_id}>
                {subject.subject_name || `درس ${subject.subject_id}`}
              </option>
            ))}
          </Select>
        </Field>
        <Field label="نوبت">
          <Select
            value={periodId}
            onChange={(e) => replaceQuery(classId, subjectId, e.target.value)}
          >
            {(data?.periods ?? []).map((period) => (
              <option key={period.id} value={period.id}>
                {period.name}
                {period.kind ? ` (${KIND_LABELS[period.kind as keyof typeof KIND_LABELS] ?? period.kind})` : ""}
              </option>
            ))}
          </Select>
        </Field>
      </div>

      {selectedPeriod ? (
        <p className="text-sm text-amber-950">
          مهلت باقی‌مانده: <CountdownTimer endsAt={selectedPeriod.grade_entry_ends_at} />
        </p>
      ) : null}

      {loading && !data ? <PageContentSkeleton rows={6} /> : null}

      {data?.students.length ? (
        <div className="overflow-auto rounded-2xl border border-[var(--border)] bg-white">
          <table className="min-w-full text-sm">
            <thead className="bg-slate-50 text-xs">
              <tr>
                <th className="px-3 py-2 text-right">کد</th>
                <th className="px-3 py-2 text-right">نام خانوادگی</th>
                <th className="px-3 py-2 text-right">نام</th>
                <th className="px-3 py-2 text-right">نام پدر</th>
                <th className="px-3 py-2 text-right">{selectedPeriod?.name || "نمره"}</th>
                <th className="px-3 py-2 text-right">توضیح معلم</th>
              </tr>
            </thead>
            <tbody>
              {data.students.map((student) => {
                const row = rows[student.id] ?? { score: "", descriptive_grade: "", teacher_comment: "" };
                return (
                  <tr key={student.id} className="border-t border-[var(--border)]">
                    <td className="px-3 py-2">{student.student_code || student.national_code || "—"}</td>
                    <td className="px-3 py-2">{student.last_name || "—"}</td>
                    <td className="px-3 py-2">{student.first_name || "—"}</td>
                    <td className="px-3 py-2">{student.father_name || "—"}</td>
                    <td className="px-3 py-2">
                      <Input
                        type={isDescriptive ? "text" : "number"}
                        className="!py-1.5 min-w-[5rem]"
                        value={isDescriptive ? row.descriptive_grade : row.score}
                        disabled={inputsDisabled}
                        readOnly={!canEnterGrades}
                        onChange={(e) =>
                          setRows((prev) => ({
                            ...prev,
                            [student.id]: isDescriptive
                              ? { ...row, descriptive_grade: e.target.value }
                              : { ...row, score: e.target.value },
                          }))
                        }
                      />
                    </td>
                    <td className="px-3 py-2">
                      <Input
                        className="!py-1.5 min-w-[10rem]"
                        value={row.teacher_comment}
                        disabled={inputsDisabled}
                        readOnly={!canEnterGrades}
                        onChange={(e) =>
                          setRows((prev) => ({
                            ...prev,
                            [student.id]: { ...row, teacher_comment: e.target.value },
                          }))
                        }
                      />
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      ) : !loading && classId ? (
        <p className="text-sm text-[var(--muted)]">دانش‌آموزی در این کلاس نیست.</p>
      ) : null}

      <div className="flex flex-wrap items-center gap-2">
        <span className="text-sm text-[var(--muted)]">
          واردشده: {data?.summary.entered ?? 0} از {data?.summary.total ?? 0}
        </span>
        {canEnterGrades ? (
          <>
            <Field label={isDescriptive ? "تکرار ارزیابی" : "تکرار نمره"}>
              <div className="flex gap-2">
                <Input value={repeatScore} onChange={(e) => setRepeatScore(e.target.value)} />
                <Button
                  variant="secondary"
                  type="button"
                  onClick={() => {
                    if (repeatScore === "") return;
                    setRows((prev) => {
                      const next = { ...prev };
                      for (const id of Object.keys(next)) {
                        const key = Number(id);
                        if (isDescriptive && !next[key].descriptive_grade) {
                          next[key] = { ...next[key], descriptive_grade: repeatScore };
                        } else if (!isDescriptive && !next[key].score) {
                          next[key] = { ...next[key], score: repeatScore };
                        }
                      }
                      return next;
                    });
                  }}
                >
                  ثبت
                </Button>
              </div>
            </Field>
            <Button disabled={saving || inputsDisabled} onClick={() => void save()}>ثبت نمرات</Button>
          </>
        ) : null}
        {classId ? (
          <ListExportActions
            exportPath="/grade-entries/teacher-workspace/export"
            filters={{
              class_room_id: classId,
              subject_id: subjectId || undefined,
              report_card_period_id: periodId || undefined,
              report_card_id: cardId,
              academic_year_id: getAcademicYearId() ?? undefined,
            }}
            filenameBase="grade-entries-teacher-workspace-export"
            onError={setError}
          />
        ) : null}
      </div>
    </div>
  );
}
