/**
 * مدل نمایشی کارنامه دانش‌آموز + آداپتور تبدیل داده‌ی بک‌اند (ReportCardService)
 * به مدل نمایشی. تمام فیلدهایی که هنوز از API نمی‌آیند (مثل امتیاز مهارت‌ها)
 * با نشانه‌ی `MOCK — …` مشخص‌اند؛ هنگام اتصال به API واقعی کافی است همان تابع
 * جایگزین شود. بقیه مقادیر مستقیماً از بک‌اند (ReportCardService::build) می‌آیند
 * و هم برای صفحه‌ی دانش‌آموز، هم پنل مدرسه، هم لینک اشتراک‌گذاری عمومی یکسان‌اند.
 */

import { persianDigits } from './persianDate';

export type EducationLevel = 'elementary' | 'middle' | 'high';

export type QualitativeLevel = 'very_good' | 'good' | 'acceptable' | 'needs_improvement';

export type AcademicStatus = 'pass' | 'fail' | 'pending';

/* ───────────── ورودی: خروجی ReportCardService::build + پراپ‌های صفحه ───────────── */

export type GradeEntry = {
  id: number;
  score: number;
  maxScore: number;
  status: 'submitted' | 'approved' | 'rejected';
  term: number | null;
  gradeType?: string | null;
};

export type SubjectInput = {
  subjectId: number;
  subjectName: string;
  coefficient: number;
  entries: GradeEntry[];
  /** میانگین وزن‌دار (بر اساس نوع نمره) همین بازه — سالانه یا یک نوبت خاص، از بک‌اند. */
  average: number | null;
  /** میانگین وزن‌دار نوبت اول — فقط برای نمای سالانه معنا دارد. */
  term1Average: number | null;
  /** میانگین وزن‌دار نوبت دوم — فقط برای نمای سالانه معنا دارد. */
  term2Average: number | null;
};

export type ReportCardStudentInput = {
  fullName: string;
  studentCode: string;
  nationalCode: string | null;
  avatarUrl: string | null;
  className: string | null;
  fieldOfStudy: string | null;
};

export type ReportCardSchoolInput = {
  name: string;
  logoUrl: string | null;
};

export type AttendanceInput = {
  presentPercent: number;
  excusedAbsence: number;
  unexcusedAbsence: number;
  totalSessions: number;
};

export type ReportCardPageProps = {
  hasStudent: boolean;
  student?: ReportCardStudentInput;
  school?: ReportCardSchoolInput;
  subjects?: SubjectInput[];
  gpa?: number | null;
  rank?: number | null;
  classSize?: number | null;
  classroomName?: string | null;
  gradeNumber?: number | null;
  attendance?: AttendanceInput;
  teacherComment?: string | null;
  academicYearTitle?: string;
  /** معدل هر نوبت (ضریب‌دار) — از ReportCardService::build، برای نمودار روند. */
  termAverages?: { term1: number | null; term2: number | null };
};

/* ───────────── خروجی: مدل نمایشی کارنامه ───────────── */

export type ReportCardStudent = {
  fullName: string;
  studentCode: string;
  nationalCode: string | null;
  gradeLabel: string;
  fieldOfStudy: string | null;
  className: string | null;
  academicYear: string | null;
  schoolName: string;
  schoolLogoUrl: string | null;
  avatarUrl: string | null;
};

export type NumericSubjectRow = {
  subjectId: number;
  subject: string;
  /** میانگین نوبت اول — برای نمای سالانه */
  term1: number | null;
  /** میانگین نوبت دوم — برای نمای سالانه */
  term2: number | null;
  continuous: number | null; // مستمر (در بازه‌ی انتخاب‌شده)
  examFinal: number | null; // پایانی (در بازه‌ی انتخاب‌شده)
  overall: number | null; // نتیجه نهایی (سالانه یا همان نوبت انتخاب‌شده)
  coefficient: number; // ضریب
  passed: boolean;
};

export type QualitativeSubjectRow = {
  subjectId: number;
  subject: string;
  term1: QualitativeLevel;
  term2: QualitativeLevel;
  finalResult: QualitativeLevel;
};

export type AttendanceInfo = {
  presentPercent: number;
  excusedAbsence: number;
  unexcusedAbsence: number;
};

export type TermAverages = {
  term1: number | null;
  term2: number | null;
  /** اختلاف نوبت دوم نسبت به اول؛ برای پیکان روند */
  trend: number | null;
};

export type ReportCardModel = {
  level: EducationLevel;
  term: number | null; // 1 | 2 | null(سالانه)
  student: ReportCardStudent;
  average: number | null;
  rank: number | null;
  classSize: number | null;
  status: AcademicStatus;
  attendance: AttendanceInfo;
  termAverages: TermAverages;
  teacherComment: string;
  /** آیا این نظر واقعاً توسط معلم ثبت شده (true) یا فقط متن پیش‌فرض است (false). */
  hasTeacherComment: boolean;
  // ابتدایی:
  qualitativeSubjects: QualitativeSubjectRow[];
  // متوسطه:
  numericSubjects: NumericSubjectRow[];
  hasData: boolean;
};

/* ───────────── تشخیص مقطع تحصیلی از شماره‌ی پایه ───────────── */

export function detectEducationLevel(gradeNumber: number | null | undefined): EducationLevel {
  if (gradeNumber == null) return 'middle';
  if (gradeNumber >= 1 && gradeNumber <= 6) return 'elementary';
  if (gradeNumber >= 7 && gradeNumber <= 9) return 'middle';
  return 'high'; // 10 تا 12
}

const GRADE_WORDS: Record<number, string> = {
  1: 'اول', 2: 'دوم', 3: 'سوم', 4: 'چهارم', 5: 'پنجم', 6: 'ششم',
  7: 'هفتم', 8: 'هشتم', 9: 'نهم', 10: 'دهم', 11: 'یازدهم', 12: 'دوازدهم',
};

export function gradeLabel(gradeNumber: number | null | undefined, level: EducationLevel): string {
  if (gradeNumber == null) return 'نامشخص';
  const word = GRADE_WORDS[gradeNumber] ?? persianDigits(gradeNumber);
  const suffix =
    level === 'elementary' ? 'ابتدایی' : level === 'middle' ? 'متوسطه اول' : 'متوسطه دوم';
  return `پایه ${word} ${suffix}`;
}

/* ───────────── متادیتای ارزیابی کیفی (ابتدایی) ───────────── */

export function qualitativeMeta(level: QualitativeLevel): {
  label: string;
  color: string;
  bg: string;
} {
  switch (level) {
    case 'very_good':
      return { label: 'خیلی خوب', color: '#16A34A', bg: 'rgba(22,163,74,0.12)' };
    case 'good':
      return { label: 'خوب', color: '#0EA678', bg: 'rgba(14,166,120,0.12)' };
    case 'acceptable':
      return { label: 'قابل قبول', color: '#F59E0B', bg: 'rgba(245,158,11,0.14)' };
    case 'needs_improvement':
    default:
      return { label: 'نیاز به تلاش', color: '#DC2626', bg: 'rgba(220,38,38,0.12)' };
  }
}

export function statusMeta(status: AcademicStatus): { label: string; color: string; bg: string } {
  switch (status) {
    case 'pass':
      return { label: 'قبول', color: '#16A34A', bg: 'rgba(22,163,74,0.12)' };
    case 'pending':
      return { label: 'در حال ثبت', color: '#64748B', bg: 'rgba(100,116,139,0.12)' };
    case 'fail':
    default:
      return { label: 'مردود', color: '#DC2626', bg: 'rgba(220,38,38,0.12)' };
  }
}

/** رنگ نمره بر اساس مقیاس ۲۰ — هماهنگ با سایر صفحات. */
export function scoreColor(value: number | null): string {
  if (value == null) return 'var(--color-text-muted)';
  if (value >= 17) return '#16A34A';
  if (value >= 14) return '#0EA678';
  if (value >= 10) return '#F59E0B';
  return '#DC2626';
}

/* ───────────── مشتق‌سازی ارزیابی کیفی از میانگین عددی ───────────── */

function numericToQualitative(avg: number | null): QualitativeLevel {
  if (avg == null) return 'acceptable';
  if (avg >= 18) return 'very_good';
  if (avg >= 15) return 'good';
  if (avg >= 12) return 'acceptable';
  return 'needs_improvement';
}

/** میانگین ورودی‌های یک نوع نمره (مستمر/پایانی) روی مقیاس ۲۰ — فقط برای نمایش زیرمجموعه، نه معدل. */
function typedAverage(entries: GradeEntry[], types: string[], term: number | null): number | null {
  const relevant = entries.filter(
    (e) =>
      e.status === 'approved' &&
      e.gradeType != null &&
      types.includes(e.gradeType) &&
      (term == null || e.term == null || e.term === term),
  );
  if (relevant.length === 0) return null;
  const sum = relevant.reduce((acc, e) => acc + (e.maxScore > 0 ? (e.score / e.maxScore) * 20 : 0), 0);
  return Math.round((sum / relevant.length) * 100) / 100;
}

const round2 = (v: number | null): number | null => (v == null ? null : Math.round(v * 100) / 100);

/* ───────────── آداپتور اصلی ───────────── */

export function buildReportCardModel(
  props: ReportCardPageProps,
  selectedTerm: number | null,
): ReportCardModel | null {
  if (!props.hasStudent || !props.student || !props.school) return null;

  const subjects = props.subjects ?? [];
  const level = detectEducationLevel(props.gradeNumber);
  const term = selectedTerm;

  const hasData = subjects.length > 0;
  const status: AcademicStatus = !hasData ? 'pending' : (props.gpa ?? 0) >= 10 ? 'pass' : 'fail';

  // term1Average/term2Average/average از بک‌اند می‌آیند (ReportCardService — وزن‌دار بر اساس
  // نوع نمره)؛ اینجا فقط بازخوانی می‌شوند تا با معدل کل و رتبه دقیقاً همخوان بمانند.
  const numericSubjects: NumericSubjectRow[] = subjects.map((s) => {
    // «مستمر/پایانی» فقط زیرمجموعه‌ی نمایشی‌اند، نه ورودی معدل — همچنان سمت کلاینت محاسبه می‌شوند.
    const continuous = typedAverage(s.entries, ['quiz', 'continuous', 'midterm'], term);
    const examFinal = typedAverage(s.entries, ['final', 'pre_final'], term);
    return {
      subjectId: s.subjectId,
      subject: s.subjectName,
      term1: s.term1Average,
      term2: s.term2Average,
      continuous,
      examFinal,
      overall: s.average,
      coefficient: s.coefficient ?? 1,
      passed: (s.average ?? 0) >= 10,
    };
  });

  const qualitativeSubjects: QualitativeSubjectRow[] = subjects.map((s) => ({
    subjectId: s.subjectId,
    subject: s.subjectName,
    term1: numericToQualitative(s.term1Average),
    term2: numericToQualitative(s.term2Average),
    finalResult: numericToQualitative(s.average),
  }));

  const term1Avg = props.termAverages?.term1 ?? null;
  const term2Avg = props.termAverages?.term2 ?? null;
  const termAverages: TermAverages = {
    term1: term1Avg,
    term2: term2Avg,
    trend: term1Avg != null && term2Avg != null ? round2(term2Avg - term1Avg) : null,
  };

  return {
    level,
    term,
    student: {
      fullName: props.student.fullName,
      studentCode: props.student.studentCode,
      nationalCode: props.student.nationalCode,
      gradeLabel: gradeLabel(props.gradeNumber, level),
      fieldOfStudy: level === 'high' ? props.student.fieldOfStudy : null,
      className: props.student.className,
      academicYear: props.academicYearTitle ?? null,
      schoolName: props.school.name,
      schoolLogoUrl: props.school.logoUrl,
      avatarUrl: props.student.avatarUrl,
    },
    average: props.gpa ?? null,
    rank: props.rank ?? null,
    classSize: props.classSize ?? null,
    status,
    attendance: props.attendance
      ? {
          presentPercent: props.attendance.presentPercent,
          excusedAbsence: props.attendance.excusedAbsence,
          unexcusedAbsence: props.attendance.unexcusedAbsence,
        }
      : { presentPercent: 100, excusedAbsence: 0, unexcusedAbsence: 0 },
    termAverages,
    teacherComment:
      props.teacherComment ??
      'در این نوبت هنوز نظر ویژه‌ای از سوی معلم ثبت نشده است.',
    hasTeacherComment: props.teacherComment != null && props.teacherComment !== '',
    qualitativeSubjects,
    numericSubjects,
    hasData,
  };
}
