"use client";

/**
 * MyGrades — 我的成绩（ai14）
 *
 * 数据源：useMyGrades GraphQL hook
 * 视图：成绩表（学科 / 考试名 / 得分 / 等级 / 日期）+ 趋势指示
 *
 * 隐私合规（01-understanding.md §12.2）：成绩属高敏感数据，
 * P3 阶段默认展示（无遮罩），P6 可加点击查看。本页仅做展示层。
 *
 * 设计依据：01-understanding.md §7（my-grades 视口）
 *          02-architecture-design.md §14.4（CSR + Suspense）
 */

import { useMyGrades } from "@/lib/graphql/hooks";
import type { GradeRecord } from "@/lib/graphql/types";

const dateFormatter = new Intl.DateTimeFormat("zh-CN", {
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
});

export default function MyGradesPage(): JSX.Element {
  const { data, fetching, error } = useMyGrades();
  const grades = data ?? [];

  // 计算趋势：相邻同科目的成绩对比
  const trendMap = computeTrendMap(grades);

  return (
    <div className="px-6 lg:px-10 py-8 lg:py-10 max-w-7xl mx-auto">
      <header className="mb-6">
        <p
          className="text-xs uppercase tracking-wider"
          style={{ color: "var(--color-ink-muted)" }}
        >
          成绩档案
        </p>
        <h1
          className="mt-2 text-3xl lg:text-4xl font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          我的成绩
        </h1>
        <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
          查看历次考试成绩与等级，箭头标识相对上次同科目考试的升降趋势。
        </p>
      </header>

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

      {fetching ? (
        <LoadingSkeleton />
      ) : error ? (
        <ErrorState message={error.message} />
      ) : grades.length === 0 ? (
        <EmptyState />
      ) : (
        <GradeTable grades={grades} trendMap={trendMap} />
      )}
    </div>
  );
}

function GradeTable({
  grades,
  trendMap,
}: {
  grades: GradeRecord[];
  trendMap: Map<string, TrendDirection>;
}): JSX.Element {
  return (
    <section aria-label="成绩列表" className="card-paper overflow-hidden">
      {/* 桌面端表格 */}
      <div className="hidden md:block">
        <table className="w-full">
          <caption className="sr-only">历次考试成绩列表</caption>
          <thead>
            <tr
              className="border-b"
              style={{ borderColor: "var(--color-rule)" }}
            >
              <Th>学科</Th>
              <Th>考试名称</Th>
              <Th align="right">得分</Th>
              <Th align="center">等级</Th>
              <Th align="center">趋势</Th>
              <Th align="right">名次</Th>
              <Th align="right">日期</Th>
            </tr>
          </thead>
          <tbody>
            {grades.map((grade) => (
              <tr
                key={grade.id}
                className="border-b last:border-b-0"
                style={{ borderColor: "var(--color-rule)" }}
              >
                <Td>{grade.subject.name}</Td>
                <Td>
                  <span
                    className="text-sm font-medium"
                    style={{ color: "var(--color-ink)" }}
                  >
                    {grade.examName}
                  </span>
                </Td>
                <Td align="right">
                  <span
                    className="text-base font-serif"
                    style={{ color: "var(--color-ink)" }}
                  >
                    {grade.score}
                  </span>
                  <span
                    className="text-xs"
                    style={{ color: "var(--color-ink-muted)" }}
                  >
                    {" "}
                    / {grade.maxScore}
                  </span>
                </Td>
                <Td align="center">
                  <span
                    className={`badge ${getBadgeClassForGrade(grade.grade)}`}
                  >
                    {grade.grade}
                  </span>
                </Td>
                <Td align="center">
                  <TrendIndicator
                    direction={trendMap.get(grade.id) ?? "stable"}
                  />
                </Td>
                <Td align="right">
                  <span
                    className="text-sm"
                    style={{ color: "var(--color-ink-muted)" }}
                  >
                    第 {grade.rank} 名
                  </span>
                </Td>
                <Td align="right">
                  <span
                    className="text-xs"
                    style={{ color: "var(--color-ink-muted)" }}
                  >
                    {dateFormatter.format(new Date(grade.submittedAt))}
                  </span>
                </Td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* 移动端卡片列表 */}
      <ul
        className="md:hidden divide-y"
        style={{ borderColor: "var(--color-rule)" }}
      >
        {grades.map((grade) => (
          <li key={grade.id} className="p-4">
            <div className="flex items-start justify-between gap-3">
              <div className="min-w-0 flex-1">
                <p
                  className="text-xs uppercase tracking-wider"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  {grade.subject.name}
                </p>
                <p
                  className="mt-1 text-sm font-medium text-truncate"
                  style={{ color: "var(--color-ink)" }}
                >
                  {grade.examName}
                </p>
              </div>
              <span
                className={`badge ${getBadgeClassForGrade(grade.grade)} flex-shrink-0`}
              >
                {grade.grade}
              </span>
            </div>
            <div className="mt-3 flex items-baseline justify-between">
              <span
                className="text-2xl font-serif"
                style={{ color: "var(--color-ink)" }}
              >
                {grade.score}
                <span
                  className="text-xs font-sans"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  {" "}
                  / {grade.maxScore}
                </span>
              </span>
              <div className="flex items-center gap-3">
                <TrendIndicator
                  direction={trendMap.get(grade.id) ?? "stable"}
                />
                <span
                  className="text-xs"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  第 {grade.rank} 名
                </span>
              </div>
            </div>
            <p
              className="mt-2 text-xs"
              style={{ color: "var(--color-ink-muted)" }}
            >
              {dateFormatter.format(new Date(grade.submittedAt))}
            </p>
          </li>
        ))}
      </ul>
    </section>
  );
}

type TrendDirection = "up" | "down" | "stable";

// 计算趋势：按 subject 分组，相邻比较（按 submittedAt 倒序）
function computeTrendMap(grades: GradeRecord[]): Map<string, TrendDirection> {
  const result = new Map<string, TrendDirection>();

  // 按学科分组
  const bySubject = new Map<string, GradeRecord[]>();
  for (const g of grades) {
    const list = bySubject.get(g.subject.id) ?? [];
    list.push(g);
    bySubject.set(g.subject.id, list);
  }

  // 每个学科内按时间正序，相邻比较得到每条记录的趋势
  for (const list of bySubject.values()) {
    const sorted = [...list].sort(
      (a, b) =>
        new Date(a.submittedAt).getTime() - new Date(b.submittedAt).getTime(),
    );
    sorted.forEach((g, idx) => {
      if (idx === 0) {
        result.set(g.id, "stable");
        return;
      }
      const prev = sorted[idx - 1];
      if (!prev) {
        result.set(g.id, "stable");
        return;
      }
      const diff = g.score - prev.score;
      if (Math.abs(diff) < 1) {
        result.set(g.id, "stable");
      } else if (diff > 0) {
        result.set(g.id, "up");
      } else {
        result.set(g.id, "down");
      }
    });
  }

  return result;
}

function TrendIndicator({
  direction,
}: {
  direction: TrendDirection;
}): JSX.Element {
  if (direction === "stable") {
    return (
      <span
        aria-label="持平"
        className="inline-flex items-center"
        style={{ color: "var(--color-ink-muted)" }}
      >
        <svg
          width="14"
          height="14"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          aria-hidden="true"
        >
          <path d="M5 12h14" />
        </svg>
      </span>
    );
  }
  if (direction === "up") {
    return (
      <span
        aria-label="上升"
        className="inline-flex items-center"
        style={{ color: "var(--color-success)" }}
      >
        <svg
          width="14"
          height="14"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          aria-hidden="true"
        >
          <path d="m18 15-6-6-6 6" />
        </svg>
      </span>
    );
  }
  return (
    <span
      aria-label="下降"
      className="inline-flex items-center"
      style={{ color: "var(--color-danger)" }}
    >
      <svg
        width="14"
        height="14"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        aria-hidden="true"
      >
        <path d="m6 9 6 6 6-6" />
      </svg>
    </span>
  );
}

function getBadgeClassForGrade(grade: string): string {
  if (grade === "优秀") return "badge-success";
  if (grade === "良好") return "badge-info";
  if (grade === "及格") return "badge-warning";
  if (grade === "不及格") return "badge-danger";
  return "badge-info";
}

// === 表格小工具 ===
function Th({
  children,
  align = "left",
}: {
  children: React.ReactNode;
  align?: "left" | "right" | "center";
}): JSX.Element {
  return (
    <th
      scope="col"
      className="px-4 py-3 text-xs uppercase tracking-wider font-sans"
      style={{
        color: "var(--color-ink-muted)",
        textAlign: align,
      }}
    >
      {children}
    </th>
  );
}

function Td({
  children,
  align = "left",
}: {
  children: React.ReactNode;
  align?: "left" | "right" | "center";
}): JSX.Element {
  return (
    <td
      className="px-4 py-3 text-sm"
      style={{
        color: "var(--color-ink)",
        textAlign: align,
      }}
    >
      {children}
    </td>
  );
}

function LoadingSkeleton(): JSX.Element {
  return (
    <div
      aria-busy="true"
      aria-live="polite"
      className="card-paper p-0 overflow-hidden"
    >
      <div className="hidden md:block" aria-hidden="true">
        <div
          className="h-10 border-b"
          style={{
            background: "var(--color-paper)",
            borderColor: "var(--color-rule)",
          }}
        />
        {[0, 1, 2, 3, 4].map((i) => (
          <div
            key={i}
            className="h-12 border-b last:border-b-0 animate-pulse"
            style={{
              background: "var(--color-rule)",
              borderColor: "var(--color-rule)",
              opacity: 0.3,
            }}
          />
        ))}
      </div>
      <div className="md:hidden space-y-3 p-4" aria-hidden="true">
        {[0, 1, 2].map((i) => (
          <div
            key={i}
            className="h-20 rounded-sm animate-pulse"
            style={{ background: "var(--color-rule)", opacity: 0.3 }}
          />
        ))}
      </div>
      <span className="sr-only">正在加载成绩列表...</span>
    </div>
  );
}

function ErrorState({ message }: { message: string }): JSX.Element {
  return (
    <div
      role="alert"
      className="card-paper p-8 text-center"
      style={{ borderColor: "var(--color-danger)" }}
    >
      <p
        className="text-base font-serif"
        style={{ color: "var(--color-danger)" }}
      >
        成绩列表加载失败
      </p>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        {message}
      </p>
      <button
        type="button"
        onClick={() => window.location.reload()}
        className="mt-4 btn-secondary text-xs"
      >
        重新加载
      </button>
    </div>
  );
}

function EmptyState(): JSX.Element {
  return (
    <div className="card-paper p-8 text-center">
      <p
        className="text-4xl font-serif"
        style={{ color: "var(--color-ink-subtle)" }}
        aria-hidden="true"
      >
        ◇
      </p>
      <p
        className="mt-4 text-base font-serif"
        style={{ color: "var(--color-ink)" }}
      >
        暂无成绩记录
      </p>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        当老师批改完考试后，这里会显示你的成绩与排名。
      </p>
    </div>
  );
}
