"use client";

/**
 * 成绩批量录入页
 *
 * 数据来源（P7 扩展，MSW mock）：
 * - GraphQL GradeEntryQuery：按 examId + classId 拉取学生成绩录入列表
 * - GraphQL SaveGradeEntriesMutation：批量保存成绩录入
 * - GraphQL ClassesQuery + ClassExamsQuery：班级 + 试卷下拉选项
 *
 * 试卷-班级年级匹配：仅展示同年级的试卷/班级（按 gradeId 过滤）
 *
 * 维护者：ai13（teacher-portal）
 */

import { useState, useMemo } from "react";
import { useQuery, useMutation } from "urql";
import Link from "next/link";
import { Loading, Empty } from "@edu/ui-components";
import { ClassesQuery, ClassExamsQuery } from "@/lib/graphql";
import type { Class, ExamItem } from "@/lib/graphql";
import { GradeEntryQuery, SaveGradeEntriesMutation } from "@/lib/graphql-p7-grades";
import type { GradeEntryItem, SaveGradeEntryInput } from "@/lib/graphql-p7-grades";

/** 单行编辑状态 */
interface EntryRow {
  studentId: string;
  score: string;
  feedback: string;
}

export default function GradeEntryPage(): React.ReactNode {
  const [classId, setClassId] = useState("");
  const [examId, setExamId] = useState("");

  // 班级列表
  const [classesResult] = useQuery({ query: ClassesQuery });
  const classes: Class[] = classesResult.data?.classes ?? [];

  // 选中班级后拉取试卷列表（同年级过滤：ClassExamsQuery 已按 classId 返回该班试卷）
  const [examsResult] = useQuery({
    query: ClassExamsQuery,
    variables: { classId },
    pause: !classId,
  });
  const exams: ExamItem[] = examsResult.data?.classExams ?? [];

  // 成绩录入列表
  const [entryResult, reexecuteEntry] = useQuery({
    query: GradeEntryQuery,
    variables: { examId, classId },
    pause: !examId || !classId,
  });
  const entries: GradeEntryItem[] = entryResult.data?.gradeEntry ?? [];

  // 批量保存 mutation
  const [saveResult, saveEntries] = useMutation(SaveGradeEntriesMutation);

  // 编辑行状态（按 studentId 索引）
  const [rows, setRows] = useState<Record<string, EntryRow>>({});
  const [submitting, setSubmitting] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);
  const [savedMsg, setSavedMsg] = useState<string | null>(null);

  // 当 entries 变化时，初始化 rows
  useMemo(() => {
    const next: Record<string, EntryRow> = {};
    entries.forEach((e) => {
      next[e.studentId] = {
        studentId: e.studentId,
        score: e.score?.toString() ?? "",
        feedback: e.feedback ?? "",
      };
    });
    setRows(next);
    setSavedMsg(null);
    setSaveError(null);
  }, [entries]);

  // 年级匹配校验：选中班级后，同年级班级列表（用于校验提示）
  const selectedClass = classes.find((c) => c.id === classId);
  const sameGradeClassNames = useMemo(() => {
    if (!selectedClass) return [];
    return classes
      .filter((c) => c.gradeId === selectedClass.gradeId)
      .map((c) => c.name);
  }, [classes, selectedClass]);

  const handleSaveAll = async () => {
    if (!examId || !classId) {
      setSaveError("请先选择班级和试卷");
      return;
    }
    const payload: SaveGradeEntryInput[] = [];
    for (const e of entries) {
      const row = rows[e.studentId];
      if (!row) continue;
      const scoreNum = Number(row.score);
      if (row.score === "" || Number.isNaN(scoreNum)) continue;
      payload.push({
        studentId: e.studentId,
        score: scoreNum,
        feedback: row.feedback.trim() || null,
      });
    }
    if (payload.length === 0) {
      setSaveError("请至少填写一条有效成绩");
      return;
    }
    setSubmitting(true);
    setSaveError(null);
    setSavedMsg(null);
    // 乐观更新：本地展示保存中状态
    const res = await saveEntries({
      input: { examId, classId, entries: payload },
    });
    setSubmitting(false);
    if (res.error) {
      setSaveError(res.error.message);
      return;
    }
    setSavedMsg(`已保存 ${res.data?.saveGradeEntries?.savedCount ?? payload.length} 条成绩`);
    // 刷新录入列表
    reexecuteEntry({ requestPolicy: "network-only" });
  };

  return (
    <div className="px-10 py-10">
      <header className="mb-8">
        <p className="mb-2">
          <Link
            href="/grades"
            className="text-tiny uppercase tracking-wide text-ink-muted hover:opacity-70"
          >
            ← 返回成绩查询
          </Link>
        </p>
        <h1 className="text-3xl font-serif text-ink">成绩批量录入</h1>
        <p className="mt-1 text-sm text-ink-muted">
          GraphQL GradeEntryQuery + SaveGradeEntriesMutation · core-edu 域（P7 扩展，MSW mock）
        </p>
      </header>

      <div className="rule-thin mb-8" />

      {/* 班级 + 试卷选择 */}
      <section className="mb-8">
        <div className="grid grid-cols-2 gap-6 mb-4">
          <div>
            <label className="block text-tiny uppercase tracking-wide text-ink-muted mb-1">
              班级
            </label>
            <select
              value={classId}
              onChange={(e) => {
                setClassId(e.target.value);
                setExamId("");
              }}
              className="w-full px-3 py-2 bg-transparent border-b border-rule text-sm font-sans text-ink focus:outline-none focus:border-accent"
            >
              <option value="">请选择班级</option>
              {classes.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-tiny uppercase tracking-wide text-ink-muted mb-1">
              试卷
            </label>
            <select
              value={examId}
              onChange={(e) => setExamId(e.target.value)}
              disabled={!classId}
              className="w-full px-3 py-2 bg-transparent border-b border-rule text-sm font-sans text-ink focus:outline-none focus:border-accent disabled:opacity-50"
            >
              <option value="">请选择试卷</option>
              {exams.map((ex) => (
                <option key={ex.id} value={ex.id}>
                  {ex.title}（{ex.totalScore} 分）
                </option>
              ))}
            </select>
          </div>
        </div>
        {selectedClass && sameGradeClassNames.length > 0 && (
          <p className="text-tiny text-ink-muted">
            同年级班级：{sameGradeClassNames.join("、")}（年级 {selectedClass.gradeId}）
          </p>
        )}
      </section>

      {!classId || !examId ? (
        <Empty
          title="请选择班级和试卷"
          description="选择班级后选择试卷，再拉取学生成绩录入列表"
        />
      ) : entryResult.fetching ? (
        <Loading lines={8} />
      ) : entryResult.error ? (
        <div className="mark-left mb-4 py-2 border-l-2 border-danger pl-md">
          <p className="text-sm px-3 text-danger">
            加载失败：{entryResult.error.message}
          </p>
        </div>
      ) : entries.length === 0 ? (
        <Empty title="暂无学生" description="该班级尚未导入学生名单" />
      ) : (
        <section>
          <div className="flex items-baseline justify-between mb-4">
            <h2 className="text-xl font-serif text-ink">
              学生成绩录入
              <span className="ml-2 text-sm font-sans text-ink-muted">
                {entries.length} 名学生
              </span>
            </h2>
            <div className="flex items-center gap-3">
              {saveError && (
                <span className="text-tiny text-danger">{saveError}</span>
              )}
              {savedMsg && !submitting && (
                <span className="text-tiny text-success">{savedMsg}</span>
              )}
              <button
                type="button"
                onClick={handleSaveAll}
                disabled={submitting}
                className="px-4 py-2 text-sm text-ink-on-accent bg-accent rounded-button hover:bg-accent-hover disabled:opacity-50"
              >
                {submitting ? "保存中..." : "保存全部"}
              </button>
            </div>
          </div>
          <div className="rule-thin mb-4" />

          {/* 录入表格 */}
          <div className="border border-rule rounded-card overflow-hidden">
            <table className="w-full text-sm">
              <thead className="bg-subtle">
                <tr>
                  <th className="px-4 py-3 text-left text-tiny uppercase tracking-wide text-ink-muted">
                    学生
                  </th>
                  <th className="px-4 py-3 text-left text-tiny uppercase tracking-wide text-ink-muted">
                    学号
                  </th>
                  <th className="px-4 py-3 text-left text-tiny uppercase tracking-wide text-ink-muted w-32">
                    分数
                  </th>
                  <th className="px-4 py-3 text-left text-tiny uppercase tracking-wide text-ink-muted">
                    反馈
                  </th>
                </tr>
              </thead>
              <tbody>
                {entries.map((e) => {
                  const row = rows[e.studentId];
                  return (
                    <tr
                      key={e.studentId}
                      className="border-t border-rule"
                    >
                      <td className="px-4 py-3 font-serif text-ink">
                        {e.studentName}
                      </td>
                      <td className="px-4 py-3 font-mono text-tiny text-ink-muted">
                        {e.studentNo}
                      </td>
                      <td className="px-4 py-3">
                        <input
                          type="number"
                          min={0}
                          max={100}
                          value={row?.score ?? ""}
                          onChange={(ev) =>
                            setRows((prev) => ({
                              ...prev,
                              [e.studentId]: {
                                studentId: e.studentId,
                                score: ev.target.value,
                                feedback: row?.feedback ?? "",
                              },
                            }))
                          }
                          className="w-24 px-2 py-1 bg-paper border border-rule rounded-button text-sm text-ink focus:outline-none focus:border-accent"
                          placeholder="0-100"
                        />
                      </td>
                      <td className="px-4 py-3">
                        <input
                          type="text"
                          value={row?.feedback ?? ""}
                          onChange={(ev) =>
                            setRows((prev) => ({
                              ...prev,
                              [e.studentId]: {
                                studentId: e.studentId,
                                score: row?.score ?? "",
                                feedback: ev.target.value,
                              },
                            }))
                          }
                          className="w-full px-2 py-1 bg-paper border border-rule rounded-button text-sm text-ink focus:outline-none focus:border-accent"
                          placeholder="可选：批改意见"
                        />
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {saveResult.data && !saveError && !submitting && (
            <p className="mt-4 text-tiny text-success">
              已保存 {saveResult.data.saveGradeEntries?.savedCount ?? 0} 条成绩记录
            </p>
          )}
        </section>
      )}
    </div>
  );
}
