"use client";

/**
 * Dashboard — 学生仪表盘（ai14）
 *
 * 数据源：useStudentDashboard + useMySchedule + useStudentGrowth GraphQL hook
 * 视图模型：avgScore / classRank / attendanceRate / learningStreakDays /
 *          upcomingHomework(3) / upcomingExams(2) / recentGrades(3) /
 *          todaySchedule / growthCurve(myScore vs classAverage)
 *
 * 设计依据：01-understanding.md §7（dashboard 视口）
 *          02-architecture-design.md §14.4（dashboard SSR + CSR）
 */

import { useMemo } from "react";
import Link from "next/link";
import {
  useStudentDashboard,
  useCurrentUser,
  useMySchedule,
  useStudentGrowth,
} from "@/lib/graphql/hooks";
import type {
  StudentDashboard,
  DashboardHomework,
  DashboardExam,
  DashboardGrade,
  ScheduleItem,
  GrowthDataPoint,
} from "@/lib/graphql/types";
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";

// 日期格式化（中文短格式）
const dateFormatter = new Intl.DateTimeFormat("zh-CN", {
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
});

function formatDueDate(iso: string): string {
  return dateFormatter.format(new Date(iso));
}

function formatPercent(rate: number): string {
  return `${(rate * 100).toFixed(1)}%`;
}

export default function DashboardPage(): JSX.Element {
  const { data, fetching, error } = useStudentDashboard();
  const { data: currentUser } = useCurrentUser();
  const { data: scheduleData } = useMySchedule();
  const { data: growthData } = useStudentGrowth();

  // 筛选今日课表
  const todaySchedule = useMemo(() => {
    if (!scheduleData) return [];
    const today = new Date().getDay();
    return scheduleData
      .filter((s) => s.dayOfWeek === today)
      .sort((a, b) => a.startTime.localeCompare(b.startTime));
  }, [scheduleData]);

  return (
    <div className="px-6 lg:px-10 py-8 lg:py-10 max-w-7xl mx-auto">
      <HeaderSection studentName={currentUser?.name} />
      <div className="rule-thin mb-8" />

      {fetching ? (
        <LoadingSkeleton />
      ) : error ? (
        <ErrorState message={error.message} />
      ) : !data ? (
        <EmptyState />
      ) : (
        <>
          <StatGrid data={data} />
          <div className="mt-8 grid grid-cols-1 lg:grid-cols-2 gap-6">
            <UpcomingHomeworkCard items={data.upcomingHomework ?? []} />
            <UpcomingExamsCard items={data.upcomingExams ?? []} />
          </div>
          <div className="mt-6 grid grid-cols-1 lg:grid-cols-2 gap-6">
            <TodayScheduleCard items={todaySchedule} />
            <GrowthCurveCard items={growthData ?? []} />
          </div>
          <div className="mt-6">
            <RecentGradesCard items={data.recentGrades ?? []} />
          </div>
        </>
      )}
    </div>
  );
}

// === 顶部欢迎区 ===
function HeaderSection({
  studentName,
}: {
  studentName: string | undefined;
}): JSX.Element {
  const today = new Intl.DateTimeFormat("zh-CN", {
    year: "numeric",
    month: "long",
    day: "numeric",
    weekday: "long",
  }).format(new Date());

  return (
    <header className="mb-6">
      <p
        className="text-xs uppercase tracking-wider"
        style={{ color: "var(--color-ink-muted)" }}
      >
        {today}
      </p>
      <h1
        className="mt-2 text-3xl lg:text-4xl font-serif"
        style={{ color: "var(--color-ink)" }}
      >
        你好，{studentName ?? "同学"}
      </h1>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        欢迎回到学习空间，继续保持你的学习节奏。
      </p>
    </header>
  );
}

// === 统计卡片网格 ===
function StatGrid({ data }: { data: StudentDashboard }): JSX.Element {
  return (
    <section
      aria-label="学习概览"
      className="grid grid-cols-2 lg:grid-cols-4 gap-4"
    >
      <StatCard
        label="平均分"
        value={data.avgScore.toFixed(1)}
        suffix="/ 100"
        accent
      />
      <StatCard label="班级排名" value={String(data.classRank)} suffix="名" />
      <StatCard label="出勤率" value={formatPercent(data.attendanceRate)} />
      <StatCard
        label="连续学习"
        value={String(data.learningStreakDays)}
        suffix="天"
      />
    </section>
  );
}

function StatCard({
  label,
  value,
  suffix,
  accent,
}: {
  label: string;
  value: string;
  suffix?: string;
  accent?: boolean;
}): JSX.Element {
  return (
    <div className="card-paper p-5 lg:p-6">
      <p
        className="text-xs uppercase tracking-wider"
        style={{ color: "var(--color-ink-muted)" }}
      >
        {label}
      </p>
      <p
        className="mt-3 text-3xl lg:text-4xl font-serif"
        style={{
          color: accent ? "var(--color-accent)" : "var(--color-ink)",
        }}
      >
        {value}
        {suffix && (
          <span
            className="ml-1 text-sm font-sans"
            style={{ color: "var(--color-ink-muted)" }}
          >
            {suffix}
          </span>
        )}
      </p>
    </div>
  );
}

// === 即将到期的作业 ===
function UpcomingHomeworkCard({
  items,
}: {
  items: DashboardHomework[];
}): JSX.Element {
  return (
    <section aria-label="即将到期的作业" className="card-paper p-6">
      <div className="flex items-baseline justify-between mb-4">
        <h2
          className="text-lg font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          即将到期的作业
        </h2>
        <Link
          href="/my-homework"
          className="text-xs hover:underline"
          style={{ color: "var(--color-accent)" }}
        >
          查看全部 →
        </Link>
      </div>
      <div className="rule-thin mb-4" />
      {items.length === 0 ? (
        <p
          className="text-sm py-6 text-center"
          style={{ color: "var(--color-ink-muted)" }}
        >
          暂无待办作业
        </p>
      ) : (
        <ul className="space-y-3">
          {items.map((hw) => (
            <li key={hw.id} className="mark-left">
              <Link
                href={`/my-homework/${hw.id}/submit`}
                className="block group"
              >
                <p
                  className="text-sm font-medium group-hover:underline"
                  style={{ color: "var(--color-ink)" }}
                >
                  {hw.title}
                </p>
                <p
                  className="mt-1 text-xs"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  {hw.subject.name} · 截止 {formatDueDate(hw.dueAt)}
                </p>
              </Link>
            </li>
          ))}
        </ul>
      )}
    </section>
  );
}

// === 即将到来的考试 ===
function UpcomingExamsCard({ items }: { items: DashboardExam[] }): JSX.Element {
  return (
    <section aria-label="即将到来的考试" className="card-paper p-6">
      <div className="flex items-baseline justify-between mb-4">
        <h2
          className="text-lg font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          即将到来的考试
        </h2>
        <Link
          href="/my-exams"
          className="text-xs hover:underline"
          style={{ color: "var(--color-accent)" }}
        >
          查看全部 →
        </Link>
      </div>
      <div className="rule-thin mb-4" />
      {items.length === 0 ? (
        <p
          className="text-sm py-6 text-center"
          style={{ color: "var(--color-ink-muted)" }}
        >
          暂无考试安排
        </p>
      ) : (
        <ul className="space-y-3">
          {items.map((exam) => (
            <li key={exam.id} className="mark-left">
              <p
                className="text-sm font-medium"
                style={{ color: "var(--color-ink)" }}
              >
                {exam.name}
              </p>
              <p
                className="mt-1 text-xs"
                style={{ color: "var(--color-ink-muted)" }}
              >
                {exam.subject.name} · {formatDueDate(exam.startsAt)} ·{" "}
                {Math.round(exam.durationSeconds / 60)} 分钟
              </p>
            </li>
          ))}
        </ul>
      )}
    </section>
  );
}

// === 最近成绩 ===
function RecentGradesCard({ items }: { items: DashboardGrade[] }): JSX.Element {
  return (
    <section aria-label="最近成绩" className="card-paper p-6">
      <div className="flex items-baseline justify-between mb-4">
        <h2
          className="text-lg font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          最近成绩
        </h2>
        <Link
          href="/my-grades"
          className="text-xs hover:underline"
          style={{ color: "var(--color-accent)" }}
        >
          查看全部 →
        </Link>
      </div>
      <div className="rule-thin mb-4" />
      {items.length === 0 ? (
        <p
          className="text-sm py-6 text-center"
          style={{ color: "var(--color-ink-muted)" }}
        >
          暂无成绩记录
        </p>
      ) : (
        <ul className="divide-y" style={{ borderColor: "var(--color-rule)" }}>
          {items.map((grade) => (
            <li
              key={grade.id}
              className="py-3 flex items-center justify-between gap-4"
            >
              <div className="min-w-0 flex-1">
                <p
                  className="text-sm font-medium text-truncate"
                  style={{ color: "var(--color-ink)" }}
                >
                  {grade.examName}
                </p>
                <p
                  className="mt-1 text-xs"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  {formatDueDate(grade.submittedAt)}
                </p>
              </div>
              <div className="text-right">
                <p
                  className="text-lg font-serif"
                  style={{ color: "var(--color-ink)" }}
                >
                  {grade.score}
                  <span
                    className="text-xs font-sans"
                    style={{ color: "var(--color-ink-muted)" }}
                  >
                    {" "}
                    / {grade.maxScore}
                  </span>
                </p>
                <span
                  className="badge badge-info mt-1"
                  aria-label={`等级 ${grade.grade}`}
                >
                  {grade.grade}
                </span>
              </div>
            </li>
          ))}
        </ul>
      )}
    </section>
  );
}

// === 今日课表 ===
function TodayScheduleCard({
  items,
}: {
  items: ScheduleItem[];
}): JSX.Element {
  return (
    <section aria-label="今日课表" className="card-paper p-6">
      <div className="flex items-baseline justify-between mb-4">
        <h2
          className="text-lg font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          今日课表
        </h2>
        <Link
          href="/schedule"
          className="text-xs hover:underline"
          style={{ color: "var(--color-accent)" }}
        >
          查看周课表 →
        </Link>
      </div>
      <div className="rule-thin mb-4" />
      {items.length === 0 ? (
        <p
          className="text-sm py-6 text-center"
          style={{ color: "var(--color-ink-muted)" }}
        >
          今日无课
        </p>
      ) : (
        <ul className="space-y-2">
          {items.map((item) => (
            <li
              key={item.id}
              className="flex items-center gap-md py-xs"
              style={{ borderLeft: "2px solid var(--color-accent)" }}
            >
              <span
                className="font-mono text-xs flex-shrink-0 pl-sm"
                style={{ color: "var(--color-ink-muted)" }}
              >
                {item.startTime}–{item.endTime}
              </span>
              <div className="min-w-0 flex-1">
                <p
                  className="text-sm font-medium text-truncate"
                  style={{ color: "var(--color-ink)" }}
                >
                  {item.subject}
                </p>
                <p
                  className="text-xs text-truncate"
                  style={{ color: "var(--color-ink-muted)" }}
                >
                  {item.teacher} · {item.classroom}
                </p>
              </div>
            </li>
          ))}
        </ul>
      )}
    </section>
  );
}

// === 成长曲线 ===
function GrowthCurveCard({
  items,
}: {
  items: GrowthDataPoint[];
}): JSX.Element {
  const chartData = useMemo(
    () =>
      items.map((p) => ({
        date: p.date.slice(5),
        myScore: p.myScore,
        classAverage: p.classAverage,
      })),
    [items],
  );

  return (
    <section aria-label="成长曲线" className="card-paper p-6">
      <div className="flex items-baseline justify-between mb-4">
        <h2
          className="text-lg font-serif"
          style={{ color: "var(--color-ink)" }}
        >
          成长曲线
        </h2>
        <span
          className="text-xs"
          style={{ color: "var(--color-ink-muted)" }}
        >
          我的成绩 vs 班级平均
        </span>
      </div>
      <div className="rule-thin mb-4" />
      {items.length === 0 ? (
        <p
          className="text-sm py-6 text-center"
          style={{ color: "var(--color-ink-muted)" }}
        >
          暂无成长数据
        </p>
      ) : (
        <div style={{ width: "100%", height: 240 }}>
          <ResponsiveContainer width="100%" height="100%">
            <LineChart
              data={chartData}
              margin={{ top: 8, right: 16, bottom: 8, left: 0 }}
            >
              <CartesianGrid
                stroke="var(--color-rule)"
                strokeDasharray="3 3"
              />
              <XAxis
                dataKey="date"
                tick={{ fill: "var(--color-ink-muted)", fontSize: 11 }}
              />
              <YAxis
                tick={{ fill: "var(--color-ink-muted)", fontSize: 11 }}
                domain={["auto", "auto"]}
              />
              <Tooltip
                contentStyle={{
                  background: "var(--color-paper)",
                  border: "1px solid var(--color-rule)",
                  borderRadius: "var(--radius-base)",
                  fontSize: 12,
                }}
                labelStyle={{ color: "var(--color-ink)" }}
              />
              <Legend
                wrapperStyle={{ fontSize: 11 }}
              />
              <Line
                type="monotone"
                dataKey="myScore"
                name="我的成绩"
                stroke="var(--color-accent)"
                strokeWidth={2}
                dot={{ r: 3, fill: "var(--color-accent)" }}
                isAnimationActive={false}
              />
              <Line
                type="monotone"
                dataKey="classAverage"
                name="班级平均"
                stroke="var(--color-ink-muted)"
                strokeWidth={1.5}
                strokeDasharray="4 4"
                dot={false}
                isAnimationActive={false}
              />
            </LineChart>
          </ResponsiveContainer>
        </div>
      )}
    </section>
  );
}

// === 加载骨架 ===
function LoadingSkeleton(): JSX.Element {
  return (
    <div aria-busy="true" aria-live="polite">
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4" aria-hidden="true">
        {[0, 1, 2, 3].map((i) => (
          <div key={i} className="card-paper p-6">
            <div
              className="h-3 w-16 rounded-sm animate-pulse"
              style={{ background: "var(--color-rule)" }}
            />
            <div
              className="mt-4 h-8 w-24 rounded-sm animate-pulse"
              style={{ background: "var(--color-rule)" }}
            />
          </div>
        ))}
      </div>
      <div className="mt-8 grid grid-cols-1 lg:grid-cols-2 gap-6">
        {[0, 1].map((i) => (
          <div key={i} className="card-paper p-6">
            <div
              className="h-4 w-32 rounded-sm animate-pulse"
              style={{ background: "var(--color-rule)" }}
            />
            <div className="mt-6 space-y-3">
              {[0, 1, 2].map((j) => (
                <div
                  key={j}
                  className="h-12 rounded-sm animate-pulse"
                  style={{ background: "var(--color-rule)" }}
                />
              ))}
            </div>
          </div>
        ))}
      </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>
  );
}
