"use client";

/**
 * AI 学情报告页面（P5）
 *
 * 数据来源（02-architecture-design.md §6 AI 辅助）：
 * - GraphQL GenerateReportMutation
 *
 * 功能：
 * - 表单：班级 / 报告类型（班级周报/月报/单生报告）/ 学生选择（单生报告时）
 * - 生成报告（mutation）+ 流式输出模拟（setInterval 逐字显示）
 * - 完整报告展示（含建议）
 * - 导出为 .md 文件
 *
 * 维护者：ai13（teacher-portal）
 */

import { useEffect, useRef, useState } from "react";
import { useMutation, useQuery } from "urql";
import { GenerateReportMutation } from "@/lib/graphql-p5";
import type { GeneratedReport, GenerateReportInput } from "@/lib/graphql-p5";
import { ClassesQuery, ClassStudentsQuery } from "@/lib/graphql";
import type { Class, Student } from "@/lib/graphql";
import { Loading } from "@edu/ui-components";

const REPORT_TYPES = ["班级周报", "月报", "单生报告"];
const STREAM_INTERVAL_MS = 12;

export default function AiReportPage(): JSX.Element {
  const [classId, setClassId] = useState("");
  const [reportType, setReportType] = useState<string>(
    REPORT_TYPES[0] ?? "班级周报",
  );
  const [studentId, setStudentId] = useState("");

  const [isGenerating, setIsGenerating] = useState(false);
  const [isStreaming, setIsStreaming] = useState(false);
  const [streamingText, setStreamingText] = useState("");
  const [generated, setGenerated] = useState<GeneratedReport | null>(null);
  const [error, setError] = useState<string | null>(null);

  const streamTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const [, generateReport] = useMutation(GenerateReportMutation);

  const [classesResult] = useQuery({ query: ClassesQuery });
  const classes = (classesResult.data?.classes as Class[] | undefined) ?? [];

  const [studentsResult] = useQuery({
    query: ClassStudentsQuery,
    variables: { classId },
    pause: !classId,
  });
  const students =
    (studentsResult.data?.classStudents as Student[] | undefined) ?? [];

  useEffect(() => {
    if (!classId) {
      const first = classes[0];
      if (first) setClassId(first.id);
    }
  }, [classes, classId]);

  useEffect(() => {
    if (reportType !== "单生报告") {
      setStudentId("");
    }
  }, [reportType]);

  useEffect(() => {
    return () => {
      if (streamTimerRef.current) clearInterval(streamTimerRef.current);
    };
  }, []);

  const handleGenerate = async (): Promise<void> => {
    if (isGenerating || isStreaming) return;
    if (reportType === "单生报告" && !studentId) {
      setError("单生报告需要选择一名学生");
      return;
    }
    setIsGenerating(true);
    setError(null);
    setGenerated(null);
    setStreamingText("");

    const input: GenerateReportInput = {
      classId,
      reportType,
      studentId: reportType === "单生报告" ? studentId : undefined,
    };

    const res = await generateReport({ input });
    setIsGenerating(false);

    if (res.error || !res.data?.generateReport) {
      setError(res.error?.message ?? "生成失败，请重试");
      return;
    }

    const rpt = res.data.generateReport as GeneratedReport;
    const full = rpt.content;

    setIsStreaming(true);
    let i = 0;
    streamTimerRef.current = setInterval(() => {
      i += 1;
      setStreamingText(full.slice(0, i));
      if (i >= full.length) {
        if (streamTimerRef.current) {
          clearInterval(streamTimerRef.current);
          streamTimerRef.current = null;
        }
        setIsStreaming(false);
        setGenerated(rpt);
      }
    }, STREAM_INTERVAL_MS);
  };

  const handleExport = (): void => {
    if (!generated) return;
    const blob = new Blob([generated.content], {
      type: "text/markdown;charset=utf-8",
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `report-${generated.id}.md`;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="px-10 py-10">
      <header className="mb-8">
        <h1 className="text-3xl font-serif text-ink">AI 学情报告</h1>
        <p className="mt-1 text-sm text-ink-muted">
          GraphQL GenerateReportMutation · 流式输出模拟（P5）
        </p>
      </header>

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

      {/* 表单 */}
      <section className="mb-8 max-w-3xl">
        <h2 className="text-xl font-serif text-ink mb-4">报告参数</h2>
        {classesResult.fetching && classes.length === 0 ? (
          <Loading lines={2} />
        ) : (
          <div className="grid grid-cols-2 gap-4">
            <label className="flex flex-col gap-1">
              <span className="text-tiny uppercase tracking-wide text-ink-muted">
                班级
              </span>
              <select
                value={classId}
                onChange={(e) => setClassId(e.target.value)}
                className="px-3 py-2 bg-transparent border-b border-rule text-sm text-ink"
              >
                {classes.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name}
                  </option>
                ))}
              </select>
            </label>
            <label className="flex flex-col gap-1">
              <span className="text-tiny uppercase tracking-wide text-ink-muted">
                报告类型
              </span>
              <select
                value={reportType}
                onChange={(e) => setReportType(e.target.value)}
                className="px-3 py-2 bg-transparent border-b border-rule text-sm text-ink"
              >
                {REPORT_TYPES.map((t) => (
                  <option key={t} value={t}>
                    {t}
                  </option>
                ))}
              </select>
            </label>
            {reportType === "单生报告" && (
              <label className="col-span-2 flex flex-col gap-1">
                <span className="text-tiny uppercase tracking-wide text-ink-muted">
                  学生
                </span>
                <select
                  value={studentId}
                  onChange={(e) => setStudentId(e.target.value)}
                  className="px-3 py-2 bg-transparent border-b border-rule text-sm text-ink"
                >
                  <option value="">请选择学生</option>
                  {students.map((s) => (
                    <option key={s.id} value={s.id}>
                      {s.name}
                    </option>
                  ))}
                </select>
                {studentsResult.fetching && (
                  <span className="text-tiny text-ink-subtle">
                    加载学生名单…
                  </span>
                )}
              </label>
            )}
          </div>
        )}

        <div className="mt-6">
          <button
            type="button"
            onClick={handleGenerate}
            disabled={isGenerating || isStreaming || !classId}
            className="px-5 py-2 text-sm text-ink-on-accent bg-accent rounded-button hover:bg-accent-hover disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {isGenerating ? "生成中…" : "生成报告"}
          </button>
        </div>
      </section>

      {error && (
        <div className="mark-left mb-6 py-2 border-l-2 border-danger pl-md">
          <p className="text-sm px-3 text-danger">{error}</p>
        </div>
      )}

      {/* 生成结果 */}
      {(isGenerating || isStreaming || streamingText || generated) && (
        <section className="mb-10">
          <div className="flex items-baseline justify-between mb-4">
            <h2 className="text-xl font-serif text-ink">
              报告内容
              {isGenerating && (
                <span className="ml-3 text-sm font-sans text-ink-muted">
                  正在请求 AI…
                </span>
              )}
              {isStreaming && (
                <span className="ml-3 text-sm font-sans text-accent">
                  流式输出中…
                </span>
              )}
            </h2>
            {generated && !isStreaming && (
              <button
                type="button"
                onClick={handleExport}
                className="text-tiny uppercase tracking-wide text-accent hover:opacity-70"
              >
                导出 .md
              </button>
            )}
          </div>
          <div className="rule-thin mb-6" />

          {isStreaming || !generated ? (
            <div className="p-6 border border-rule rounded-card bg-subtle whitespace-pre-wrap text-sm text-ink min-h-24 font-mono">
              {streamingText}
              {isStreaming && (
                <span className="inline-block w-2 h-4 ml-0.5 bg-accent animate-pulse align-middle" />
              )}
            </div>
          ) : (
            <div className="p-6 border border-rule rounded-card bg-subtle">
              <p className="text-sm text-ink-muted mb-4">{generated.summary}</p>
              <pre className="whitespace-pre-wrap text-sm text-ink font-mono leading-relaxed mb-6">
                {generated.content}
              </pre>
              <div className="pt-4 border-t border-rule">
                <h3 className="text-sm font-serif text-ink mb-3">教学建议</h3>
                <ul className="space-y-2">
                  {generated.recommendations.map((rec, idx) => (
                    <li
                      key={idx}
                      className="text-sm text-ink-muted flex gap-2"
                    >
                      <span className="text-accent font-mono">{idx + 1}.</span>
                      <span>{rec}</span>
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          )}
        </section>
      )}
    </div>
  );
}
