"use client";

/**
 * 学情诊断页（ai14，P4，路由 /dashboard/weakness）
 *
 * - 消费 useMyWeakness 查询：科目掌握度雷达图 + 薄弱知识点卡片
 * - 消费 useMyMasterySummary 查询：知识点掌握度雷达图 + 置信度等级
 * - 消费 useMyDiagnosticReports 查询：诊断报告列表（优势/弱项/建议）
 *
 * 三态覆盖：加载 / 错误 / 空
 */

import { useMemo } from "react";
import {
  PolarAngleAxis,
  PolarGrid,
  PolarRadiusAxis,
  Radar,
  RadarChart,
  ResponsiveContainer,
  Tooltip,
} from "recharts";
import {
  useMyDiagnosticReports,
  useMyMasterySummary,
  useMyWeakness,
} from "@/lib/graphql/hooks";
import type {
  ConfidenceLevel,
  DiagnosticReport,
  RecommendedAction,
  WeaknessPoint,
} from "@/lib/graphql/types";

interface SubjectRadarDatum {
  subject: string;
  mastery: number;
  fullMark: number;
}

interface KnowledgeRadarDatum {
  knowledge: string;
  mastery: number;
  fullMark: number;
}

const RECOMMENDED_ACTION_LABEL: Record<RecommendedAction, string> = {
  review: "建议复习",
  practice: "建议练习",
  mastered: "已掌握",
};

const CONFIDENCE_LEVEL_LABEL: Record<ConfidenceLevel, string> = {
  low: "低置信度",
  medium: "中置信度",
  high: "高置信度",
};

const CONFIDENCE_LEVEL_COLOR: Record<ConfidenceLevel, string> = {
  low: "var(--color-danger)",
  medium: "var(--color-warning)",
  high: "var(--color-success)",
};

function masteryPercent(mastery: number): number {
  return Math.round(Math.max(0, Math.min(1, mastery)) * 100);
}

/** 按科目聚合平均掌握度 */
function aggregateBySubject(items: WeaknessPoint[]): SubjectRadarDatum[] {
  const map = new Map<string, { sum: number; count: number }>();
  for (const item of items) {
    const name = item.subject.name;
    const prev = map.get(name) ?? { sum: 0, count: 0 };
    prev.sum += masteryPercent(item.mastery);
    prev.count += 1;
    map.set(name, prev);
  }
  return Array.from(map.entries()).map(([subject, { sum, count }]) => ({
    subject,
    mastery: count > 0 ? Math.round(sum / count) : 0,
    fullMark: 100,
  }));
}

/** 排序诊断报告（按 createdAt 降序） */
function sortReportsByDateDesc(reports: DiagnosticReport[]): DiagnosticReport[] {
  return [...reports].sort((a, b) => {
    const ta = new Date(a.createdAt).getTime();
    const tb = new Date(b.createdAt).getTime();
    return tb - ta;
  });
}

export default function WeaknessPage(): React.ReactNode {
  const {
    data: weaknessData,
    fetching: weaknessFetching,
    error: weaknessError,
    reexecute: reexecuteWeakness,
  } = useMyWeakness();
  const {
    data: masteryData,
    fetching: masteryFetching,
    error: masteryError,
    reexecute: reexecuteMastery,
  } = useMyMasterySummary();
  const {
    data: reportsData,
    fetching: reportsFetching,
    error: reportsError,
    reexecute: reexecuteReports,
  } = useMyDiagnosticReports();

  const items = weaknessData ?? [];
  const radarData = useMemo(() => aggregateBySubject(items), [items]);
  const masteryRadarData = useMemo<KnowledgeRadarDatum[]>(() => {
    if (!masteryData) return [];
    return masteryData.mastery.map((m) => ({
      knowledge: m.knowledgePointName,
      mastery: Math.round(Math.max(0, Math.min(100, m.masteryLevel))),
      fullMark: 100,
    }));
  }, [masteryData]);
  const sortedReports = useMemo(
    () => (reportsData ? sortReportsByDateDesc(reportsData) : []),
    [reportsData],
  );

  return (
    <main
      className="px-md py-lg max-w-4xl mx-auto"
      aria-labelledby="weakness-title"
    >
      <header className="mb-lg">
        <h1 id="weakness-title" className="font-serif text-2xl text-ink">
          学情诊断
        </h1>
        <p className="mt-xs text-sm text-ink-muted">
          各科目与知识点掌握度雷达图 + 诊断报告
        </p>
      </header>

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

      {/* 综合掌握度概览（来自 masterySummary） */}
      {masteryFetching ? (
        <p className="text-sm text-ink-muted mb-lg" aria-live="polite">
          加载掌握度摘要…
        </p>
      ) : masteryError ? (
        <div className="mark-left py-md px-md mb-md" aria-live="assertive">
          <p className="text-sm text-ink">
            {masteryError.message || "掌握度摘要加载失败"}
          </p>
          <button
            type="button"
            className="btn-secondary mt-sm"
            onClick={() => reexecuteMastery()}
          >
            重试
          </button>
        </div>
      ) : masteryData ? (
        <section
          className="card-paper p-lg mb-lg"
          aria-label="掌握度概览"
        >
          <div className="flex items-center justify-between gap-md flex-wrap">
            <div>
              <h2 className="font-serif text-base text-ink mb-xs">
                综合掌握度
              </h2>
              <p className="text-xs text-ink-subtle">
                覆盖 {masteryData.totalKnowledgePoints} 个知识点
              </p>
            </div>
            <div className="flex items-center gap-md">
              <div className="text-right">
                <p className="text-3xl font-serif text-ink">
                  {masteryData.averageMastery}
                  <span className="text-base text-ink-muted">%</span>
                </p>
                <p className="text-xs text-ink-subtle">平均掌握度</p>
              </div>
              <span
                className="badge"
                style={{
                  color: CONFIDENCE_LEVEL_COLOR[masteryData.confidenceLevel],
                  borderColor: CONFIDENCE_LEVEL_COLOR[masteryData.confidenceLevel],
                }}
              >
                {CONFIDENCE_LEVEL_LABEL[masteryData.confidenceLevel]}
              </span>
            </div>
          </div>
        </section>
      ) : null}

      {/* 知识点掌握度雷达图（来自 masterySummary） */}
      {masteryData && masteryRadarData.length > 0 && (
        <section
          className="card-paper p-lg mb-lg"
          aria-label="知识点掌握度雷达图"
        >
          <h2 className="font-serif text-base text-ink mb-md">
            知识点掌握度
          </h2>
          <div style={{ width: "100%", height: 320 }}>
            <ResponsiveContainer width="100%" height="100%">
              <RadarChart data={masteryRadarData} outerRadius="70%">
                <PolarGrid stroke="var(--color-rule)" />
                <PolarAngleAxis
                  dataKey="knowledge"
                  tick={{ fill: "var(--color-ink-muted)", fontSize: 11 }}
                />
                <PolarRadiusAxis
                  angle={90}
                  domain={[0, 100]}
                  tick={{ fill: "var(--color-ink-subtle)", fontSize: 10 }}
                />
                <Radar
                  name="掌握度"
                  dataKey="mastery"
                  stroke="var(--color-accent)"
                  fill="var(--color-accent)"
                  fillOpacity={0.35}
                />
                <Tooltip
                  contentStyle={{
                    background: "var(--color-paper)",
                    border: "1px solid var(--color-rule)",
                    borderRadius: "var(--radius-base)",
                    fontSize: 12,
                  }}
                  labelStyle={{ color: "var(--color-ink)" }}
                />
              </RadarChart>
            </ResponsiveContainer>
          </div>
        </section>
      )}

      {/* 科目掌握度雷达图（来自 weakness 聚合） */}
      {weaknessFetching ? (
        <p className="text-sm text-ink-muted mb-lg" aria-live="polite">
          加载中…
        </p>
      ) : weaknessError ? (
        <div className="mark-left py-md px-md mb-md" aria-live="assertive">
          <p className="text-sm text-ink">
            {weaknessError.message || "加载失败"}
          </p>
          <button
            type="button"
            className="btn-secondary mt-sm"
            onClick={() => reexecuteWeakness()}
          >
            重试
          </button>
        </div>
      ) : items.length === 0 ? (
        <p className="text-sm text-ink-muted mb-lg" role="status">
          暂无薄弱知识点数据，继续保持！
        </p>
      ) : (
        <>
          <section
            className="card-paper p-lg mb-lg"
            aria-label="科目掌握度雷达图"
          >
            <h2 className="font-serif text-base text-ink mb-md">科目掌握度</h2>
            <div style={{ width: "100%", height: 320 }}>
              <ResponsiveContainer width="100%" height="100%">
                <RadarChart data={radarData} outerRadius="70%">
                  <PolarGrid stroke="var(--color-rule)" />
                  <PolarAngleAxis
                    dataKey="subject"
                    tick={{ fill: "var(--color-ink-muted)", fontSize: 12 }}
                  />
                  <PolarRadiusAxis
                    angle={90}
                    domain={[0, 100]}
                    tick={{ fill: "var(--color-ink-subtle)", fontSize: 10 }}
                  />
                  <Radar
                    name="掌握度"
                    dataKey="mastery"
                    stroke="var(--color-accent)"
                    fill="var(--color-accent)"
                    fillOpacity={0.35}
                  />
                  <Tooltip
                    contentStyle={{
                      background: "var(--color-paper)",
                      border: "1px solid var(--color-rule)",
                      borderRadius: "var(--radius-base)",
                      fontSize: 12,
                    }}
                    labelStyle={{ color: "var(--color-ink)" }}
                  />
                </RadarChart>
              </ResponsiveContainer>
            </div>
          </section>

          {/* 薄弱知识点卡片 */}
          <section aria-label="薄弱知识点列表" className="mb-lg">
            <h2 className="font-serif text-base text-ink mb-md">薄弱知识点</h2>
            <ul className="space-y-md">
              {items.map((item: WeaknessPoint) => {
                const pct = masteryPercent(item.mastery);
                const subjectName = item.subject.name;
                return (
                  <li key={item.id}>
                    <article className="card-paper p-md">
                      <div className="flex items-center justify-between gap-md mb-xs">
                        <span className="badge badge-info">{subjectName}</span>
                        <span
                          className="text-sm"
                          style={{
                            color:
                              pct < 50
                                ? "var(--color-danger)"
                                : "var(--color-warning)",
                          }}
                          aria-label={`掌握度 ${pct}%`}
                        >
                          掌握度 {pct}%
                        </span>
                      </div>
                      <p className="font-serif text-base text-ink">
                        {item.knowledgePointName}
                      </p>
                      <p className="mt-xs text-xs text-ink-subtle">
                        错误 {item.wrongCount} 次 · 最近：{item.lastWrongAt}
                      </p>
                      <p className="mt-xs text-sm text-ink-muted">
                        <span className="text-ink-subtle">建议：</span>
                        {RECOMMENDED_ACTION_LABEL[item.recommendedAction]}
                      </p>
                    </article>
                  </li>
                );
              })}
            </ul>
          </section>
        </>
      )}

      {/* 诊断报告列表（来自 diagnosticReports） */}
      <section aria-label="诊断报告列表">
        <h2 className="font-serif text-base text-ink mb-md">诊断报告</h2>
        {reportsFetching ? (
          <p className="text-sm text-ink-muted" aria-live="polite">
            加载诊断报告…
          </p>
        ) : reportsError ? (
          <div className="mark-left py-md px-md" aria-live="assertive">
            <p className="text-sm text-ink">
              {reportsError.message || "诊断报告加载失败"}
            </p>
            <button
              type="button"
              className="btn-secondary mt-sm"
              onClick={() => reexecuteReports()}
            >
              重试
            </button>
          </div>
        ) : sortedReports.length === 0 ? (
          <p className="text-sm text-ink-muted" role="status">
            暂无诊断报告。
          </p>
        ) : (
          <ul className="space-y-md">
            {sortedReports.map((report) => (
              <li key={report.id}>
                <DiagnosticReportCard report={report} />
              </li>
            ))}
          </ul>
        )}
      </section>
    </main>
  );
}

/** 诊断报告卡片 */
function DiagnosticReportCard({
  report,
}: {
  report: DiagnosticReport;
}): JSX.Element {
  const reportDate = new Date(report.createdAt);
  const dateLabel = isNaN(reportDate.getTime())
    ? report.createdAt
    : reportDate.toLocaleDateString("zh-CN", {
        year: "numeric",
        month: "long",
        day: "numeric",
      });

  return (
    <article className="card-paper p-md">
      <div className="flex items-center justify-between gap-md mb-xs flex-wrap">
        <div className="flex items-center gap-sm flex-wrap">
          <span className="badge badge-info">{report.period ?? "—"}</span>
          {report.overallScore !== null && (
            <span
              className="text-sm font-serif"
              style={{ color: "var(--color-ink)" }}
            >
              综合分 {report.overallScore}
            </span>
          )}
        </div>
        <span className="text-xs text-ink-subtle">{dateLabel}</span>
      </div>

      {report.summary && (
        <p className="text-sm text-ink mt-xs">{report.summary}</p>
      )}

      {report.strengths && report.strengths.length > 0 && (
        <div className="mt-sm">
          <p className="text-xs font-serif text-ink mb-xs">优势</p>
          <ul className="space-y-xs">
            {report.strengths.map((s, i) => (
              <li
                key={i}
                className="text-xs text-ink-muted flex items-start gap-xs"
              >
                <span
                  style={{ color: "var(--color-success)" }}
                  aria-hidden="true"
                >
                  ✓
                </span>
                <span>{s}</span>
              </li>
            ))}
          </ul>
        </div>
      )}

      {report.weaknesses && report.weaknesses.length > 0 && (
        <div className="mt-sm">
          <p className="text-xs font-serif text-ink mb-xs">弱项</p>
          <ul className="space-y-xs">
            {report.weaknesses.map((w, i) => (
              <li
                key={i}
                className="text-xs text-ink-muted flex items-start gap-xs"
              >
                <span
                  style={{ color: "var(--color-warning)" }}
                  aria-hidden="true"
                >
                  !
                </span>
                <span>{w}</span>
              </li>
            ))}
          </ul>
        </div>
      )}

      {report.recommendations && report.recommendations.length > 0 && (
        <div className="mt-sm">
          <p className="text-xs font-serif text-ink mb-xs">建议</p>
          <ul className="space-y-xs">
            {report.recommendations.map((r, i) => (
              <li
                key={i}
                className="text-xs text-ink-muted flex items-start gap-xs"
              >
                <span
                  style={{ color: "var(--color-accent)" }}
                  aria-hidden="true"
                >
                  →
                </span>
                <span>{r}</span>
              </li>
            ))}
          </ul>
        </div>
      )}
    </article>
  );
}
