/**
 * Mock 扩展成绩数据（P7：成绩完整子模块）
 *
 * 维护者：ai13（teacher-portal）
 *
 * 覆盖：
 * - 班级成绩统计（5 个班级 × 6 学科）
 * - 学生成绩趋势（6 个月，3 个学生）
 * - 学科对比、班级对比、知识点掌握度
 * - 报告卡数据（5 学生 × 4 学期 × 6 学科）
 * - 成绩录入列表生成器
 */

import type {
  GradeEntryItem,
  GradeStats,
  GradeRanking,
  GradeAnalytics,
  GradeTrendPoint,
  GradeDistributionBand,
  SubjectComparisonItem,
  ClassComparisonItem,
  KnowledgeMasteryItem,
  ReportCard,
  ReportCardSubject,
  SaveGradeEntriesInput,
  SaveGradeEntriesResult,
} from "@/lib/graphql-p7-grades";

/** 6 个学科 */
export const SUBJECTS = [
  "语文",
  "数学",
  "英语",
  "物理",
  "化学",
  "生物",
] as const;

/** 5 个班级（含 classes.ts 现有 3 个 + 扩展 2 个） */
export const EXTENDED_CLASSES = [
  { id: "550e8400-e29b-41d4-a716-446655440010", name: "高三(1)班", gradeId: "grade-12" },
  { id: "550e8400-e29b-41d4-a716-446655440011", name: "高三(2)班", gradeId: "grade-12" },
  { id: "550e8400-e29b-41d4-a716-446655440012", name: "高三(3)班", gradeId: "grade-12" },
  { id: "550e8400-e29b-41d4-a716-446655440013", name: "高三(4)班", gradeId: "grade-12" },
  { id: "550e8400-e29b-41d4-a716-446655440014", name: "高三(5)班", gradeId: "grade-12" },
] as const;

/** 6 个月标签（趋势 X 轴） */
const MONTHS = ["1月", "2月", "3月", "4月", "5月", "6月"] as const;

/** 5 个知识点 */
const KNOWLEDGE_POINTS = [
  "函数与导数",
  "数列",
  "立体几何",
  "解析几何",
  "概率统计",
] as const;

/** 班级平均分基准（用于生成稳定 mock 数据） */
const CLASS_AVG_BASE: Record<string, number> = {
  "550e8400-e29b-41d4-a716-446655440010": 78,
  "550e8400-e29b-41d4-a716-446655440011": 82,
  "550e8400-e29b-41d4-a716-446655440012": 75,
  "550e8400-e29b-41d4-a716-446655440013": 80,
  "550e8400-e29b-41d4-a716-446655440014": 85,
};

/** 学科难度系数（用于在班级平均基础上调整学科均分） */
const SUBJECT_DIFFICULTY: Record<string, number> = {
  语文: 0,
  数学: -5,
  英语: 2,
  物理: -8,
  化学: -3,
  生物: 3,
};

/** 确定性伪随机（基于 seed，保证同输入同输出） */
function seededRandom(seed: number): number {
  const x = Math.sin(seed) * 10000;
  return x - Math.floor(x);
}

/** 基于字符串生成 seed */
function strToSeed(s: string): number {
  let h = 0;
  for (let i = 0; i < s.length; i++) {
    h = (h * 31 + s.charCodeAt(i)) | 0;
  }
  return Math.abs(h) + 1;
}

/** 计算等级 */
function scoreToLevel(score: number): GradeRanking["level"] {
  if (score >= 90) return "A";
  if (score >= 80) return "B";
  if (score >= 70) return "C";
  if (score >= 60) return "D";
  return "E";
}

/** 计算中位数 */
function median(values: number[]): number {
  if (values.length === 0) return 0;
  const sorted = [...values].sort((a, b) => a - b);
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2 !== 0
    ? (sorted[mid] ?? 0)
    : ((sorted[mid - 1] ?? 0) + (sorted[mid] ?? 0)) / 2;
}

/** 计算标准差 */
function stdDev(values: number[]): number {
  if (values.length === 0) return 0;
  const avg = values.reduce((acc, v) => acc + v, 0) / values.length;
  const variance =
    values.reduce((acc, v) => acc + (v - avg) ** 2, 0) / values.length;
  return Math.round(Math.sqrt(variance) * 10) / 10;
}

/** 生成班级学生成绩排名（30 名学生） */
function generateClassRankings(
  classId: string,
  subject: string,
): Array<{ studentId: string; studentName: string; studentNo: string; totalScore: number }> {
  const base = CLASS_AVG_BASE[classId] ?? 78;
  const adj = SUBJECT_DIFFICULTY[subject] ?? 0;
  const target = base + adj;
  const students: Array<{
    studentId: string;
    studentName: string;
    studentNo: string;
    totalScore: number;
  }> = [];
  for (let i = 1; i <= 30; i++) {
    const seed = strToSeed(`${classId}-${subject}-${i}`);
    // 围绕 target 上下波动 ±15
    const delta = Math.round((seededRandom(seed) - 0.5) * 30);
    const score = Math.max(0, Math.min(100, target + delta));
    const studentNo = `2026${String(i).padStart(3, "0")}`;
    students.push({
      studentId: `stu-${classId.slice(-4)}-${String(i).padStart(3, "0")}`,
      studentName: `学生${String(i).padStart(2, "0")}`,
      studentNo,
      totalScore: score,
    });
  }
  students.sort((a, b) => b.totalScore - a.totalScore);
  return students;
}

/** 按班级 + 学科生成成绩统计 */
export function generateGradeStats(
  classId: string,
  subject: string,
): GradeStats {
  const cls = EXTENDED_CLASSES.find((c) => c.id === classId);
  const className = cls?.name ?? "未知班级";
  const ranked = generateClassRankings(classId, subject);
  const scores = ranked.map((s) => s.totalScore);
  const sum = scores.reduce((acc, s) => acc + s, 0);
  const avg = Math.round((sum / scores.length) * 10) / 10;
  const passCount = scores.filter((s) => s >= 60).length;
  const rankings: GradeRanking[] = ranked.map((s, i) => ({
    rank: i + 1,
    studentId: s.studentId,
    studentName: s.studentName,
    studentNo: s.studentNo,
    totalScore: s.totalScore,
    level: scoreToLevel(s.totalScore),
  }));
  return {
    classId,
    className,
    subject,
    avg,
    median: Math.round(median(scores) * 10) / 10,
    max: Math.max(...scores),
    min: Math.min(...scores),
    passRate: Math.round((passCount / scores.length) * 1000) / 10,
    stdDev: stdDev(scores),
    totalCount: scores.length,
    rankings,
  };
}

/** 生成成绩录入列表（按 examId + classId） */
export function generateGradeEntries(
  examId: string,
  classId: string,
): GradeEntryItem[] {
  const studentCount = 30;
  const base = CLASS_AVG_BASE[classId] ?? 78;
  const items: GradeEntryItem[] = [];
  for (let i = 1; i <= studentCount; i++) {
    const seed = strToSeed(`${examId}-${classId}-${i}`);
    const delta = Math.round((seededRandom(seed) - 0.5) * 30);
    const score = Math.max(0, Math.min(100, base + delta));
    const feedback =
      score < 60 ? "需加强基础" : score >= 90 ? "表现优秀" : null;
    items.push({
      studentId: `stu-${classId.slice(-4)}-${String(i).padStart(3, "0")}`,
      studentName: `学生${String(i).padStart(2, "0")}`,
      studentNo: `2026${String(i).padStart(3, "0")}`,
      score: i <= 20 ? score : null, // 后 10 名未录入
      feedback: i <= 20 ? feedback : null,
    });
  }
  return items;
}

/** 批量保存成绩录入（mock：返回 savedCount） */
export function saveGradeEntries(
  input: SaveGradeEntriesInput,
): SaveGradeEntriesResult {
  return {
    examId: input.examId,
    classId: input.classId,
    savedCount: input.entries.length,
  };
}

/** 生成趋势数据（6 个月，含 avg/max/min） */
function generateTrend(classId: string): GradeTrendPoint[] {
  const base = CLASS_AVG_BASE[classId] ?? 78;
  return MONTHS.map((m, i) => {
    const seed = strToSeed(`${classId}-trend-${i}`);
    const delta = Math.round((seededRandom(seed) - 0.5) * 6);
    const avg = Math.max(0, Math.min(100, base + delta));
    return {
      month: m,
      avg,
      max: Math.min(100, avg + 12),
      min: Math.max(0, avg - 15),
    };
  });
}

/** 生成分数分布（5 段） */
function generateDistribution(classId: string): GradeDistributionBand[] {
  const base = CLASS_AVG_BASE[classId] ?? 78;
  const bands = [
    { label: "0-59", min: 0, max: 59 },
    { label: "60-69", min: 60, max: 69 },
    { label: "70-79", min: 70, max: 79 },
    { label: "80-89", min: 80, max: 89 },
    { label: "90-100", min: 90, max: 100 },
  ];
  // 班级越强，高分段越多
  const skew = (base - 75) / 10;
  return bands.map((b, i) => {
    const seed = strToSeed(`${classId}-dist-${i}`);
    const baseCount = [4, 6, 9, 8, 3][i] ?? 5;
    const adj = Math.round(skew * (i - 2) * 1.5);
    const count = Math.max(0, baseCount + adj + Math.round((seededRandom(seed) - 0.5) * 2));
    return { ...b, count };
  });
}

/** 生成学科对比 */
function generateSubjectComparison(classId: string): SubjectComparisonItem[] {
  const base = CLASS_AVG_BASE[classId] ?? 78;
  return SUBJECTS.map((s) => {
    const adj = SUBJECT_DIFFICULTY[s] ?? 0;
    const seed = strToSeed(`${classId}-subj-${s}`);
    const noise = Math.round((seededRandom(seed) - 0.5) * 4);
    return { subject: s, avg: Math.max(0, Math.min(100, base + adj + noise)) };
  });
}

/** 生成班级对比（含显著性） */
function generateClassComparison(classId: string): ClassComparisonItem[] {
  const targetAvg = CLASS_AVG_BASE[classId] ?? 78;
  return EXTENDED_CLASSES.map((c) => {
    const clsAvg = CLASS_AVG_BASE[c.id] ?? 78;
    const diff = Math.abs(clsAvg - targetAvg);
    // 差距 ≥ 6 视为显著
    const significant = diff >= 6;
    return {
      classId: c.id,
      className: c.name,
      avg: clsAvg,
      significant,
    };
  });
}

/** 生成知识点掌握度 */
function generateKnowledgeMastery(classId: string): KnowledgeMasteryItem[] {
  const base = CLASS_AVG_BASE[classId] ?? 78;
  return KNOWLEDGE_POINTS.map((kp) => {
    const seed = strToSeed(`${classId}-kp-${kp}`);
    const delta = Math.round((seededRandom(seed) - 0.5) * 20);
    return {
      knowledgePoint: kp,
      mastery: Math.max(30, Math.min(98, base + delta)),
    };
  });
}

/** 按班级生成成绩分析聚合 */
export function generateGradeAnalytics(classId: string): GradeAnalytics {
  const cls = EXTENDED_CLASSES.find((c) => c.id === classId);
  return {
    classId,
    className: cls?.name ?? "未知班级",
    trend: generateTrend(classId),
    distribution: generateDistribution(classId),
    subjectComparison: generateSubjectComparison(classId),
    classComparison: generateClassComparison(classId),
    knowledgeMastery: generateKnowledgeMastery(classId),
  };
}

// ============ 报告卡数据（5 学生 × 4 学期 × 6 学科） ============

/** 5 名学生（默认从高三(1)班抽取） */
const REPORT_STUDENTS = [
  { id: "stu-0010-001", name: "张明", no: "2026001" },
  { id: "stu-0010-002", name: "李华", no: "2026002" },
  { id: "stu-0010-003", name: "王芳", no: "2026003" },
  { id: "stu-0010-004", name: "赵磊", no: "2026004" },
  { id: "stu-0010-005", name: "陈静", no: "2026005" },
] as const;

/** 4 个学期 */
const SEMESTERS = [
  { year: "2025-2026", semester: "1" },
  { year: "2025-2026", semester: "2" },
  { year: "2026-2027", semester: "1" },
  { year: "2026-2027", semester: "2" },
] as const;

const TEACHER_NAMES = ["王老师", "刘老师", "陈老师", "杨老师", "周老师", "吴老师"];

const COMMENTS = [
  "学习态度端正，基础扎实，望继续保持。",
  "本学期进步明显，望戒骄戒躁，再接再厉。",
  "理科较强，语文需加强阅读积累。",
  "全面发展，各科均衡，表现优异。",
  "数理偏弱，建议加强逻辑训练。",
];

/** 按学生 ID + 学年 + 学期生成报告卡 */
export function generateReportCard(
  studentId: string,
  academicYear?: string,
  semester?: string,
): ReportCard | null {
  const stu = REPORT_STUDENTS.find((s) => s.id === studentId);
  if (!stu) {
    // 未匹配：用兜底学生数据
    return null;
  }
  const term = SEMESTERS.find(
    (t) =>
      (academicYear ? t.year === academicYear : true) &&
      (semester ? t.semester === semester : true),
  ) ?? SEMESTERS[0];
  if (!term) return null;

  const baseSeed = strToSeed(`${stu.id}-${term.year}-${term.semester}`);
  const baseScore = 70 + Math.round(seededRandom(baseSeed) * 20);

  const subjects: ReportCardSubject[] = SUBJECTS.map((s, i) => {
    const seed = strToSeed(`${stu.id}-${s}-${term.year}`);
    const delta = Math.round((seededRandom(seed) - 0.5) * 16);
    const score = Math.max(0, Math.min(100, baseScore + delta));
    return {
      subject: s,
      score,
      rank: 1 + ((i + Math.floor(seededRandom(seed) * 10)) % 30),
      teacherName: TEACHER_NAMES[i] ?? "未知",
    };
  });

  const totalScore = subjects.reduce((acc, s) => acc + s.score, 0);
  const commentIdx = Math.floor(seededRandom(baseSeed) * COMMENTS.length);

  return {
    studentId: stu.id,
    studentName: stu.name,
    studentNo: stu.no,
    className: "高三(1)班",
    academicYear: term.year,
    semester: term.semester,
    subjects,
    totalScore,
    classRank: 1 + (Math.floor(seededRandom(baseSeed + 1) * 30)),
    classSize: 32,
    gradeRank: 1 + (Math.floor(seededRandom(baseSeed + 2) * 150)),
    gradeSize: 150,
    teacherComment: COMMENTS[commentIdx] ?? COMMENTS[0] ?? "",
  };
}

/** 报告卡可用学生列表 */
export const REPORT_CARD_STUDENTS = REPORT_STUDENTS;

/** 报告卡可用学期列表 */
export const REPORT_CARD_SEMESTERS = SEMESTERS;
