/**
 * Mock 请假申请 + 调课申请数据（P7-admin：请假/调课子模块）
 *
 * 维护者：ai13（teacher-portal）
 *
 * 覆盖：
 * - 15 条请假申请（含 pending/approved/rejected 三种状态）
 * - 10 条调课申请（含 ADJUST/SUBSTITUTE 两种类型）
 */

import type {
  LeaveRequest,
  LeaveRequestsFilter,
  LeaveRequestsResult,
  LeaveStatus,
  LeaveType,
  ApproveLeaveRequestInput,
  ApproveLeaveRequestResult,
  SubmitLeaveRequestInput,
  SubmitLeaveRequestResult,
  ScheduleChange,
  ScheduleChangeType,
  ScheduleChangeStatus,
  ScheduleChangesResult,
  SubmitScheduleChangeInput,
  SubmitScheduleChangeResult,
} from "@/lib/graphql-p7-admin";
import type { DataScope } from "@/lib/graphql";
import { EXTENDED_CLASSES, SUBJECTS } from "./grades-extended";

/** 教师 ID 列表 */
const TEACHERS = [
  { id: "u-001", name: "王老师", role: "teacher" },
  { id: "u-002", name: "刘老师", role: "teacher" },
  { id: "u-003", name: "陈老师", role: "teacher" },
  { id: "u-004", name: "杨老师", role: "teacher" },
  { id: "u-005", name: "周老师", role: "teacher" },
  { id: "u-006", name: "吴老师", role: "head_teacher" },
  { id: "u-007", name: "郑老师", role: "teacher" },
  { id: "u-008", name: "孙老师", role: "teacher" },
] as const;

/** 审批人 ID（教务主任） */
const REVIEWER = { id: "u-admin-01", name: "教务主任" };

/** 请假原因模板 */
const LEAVE_REASONS = [
  "感冒发烧，需在家休养",
  "家中突发急事",
  "年度体检",
  "陪同家人就医",
  "参加校外培训",
  "处理个人事务",
  "感冒咳嗽",
  "事务处理",
  "婚假",
  "事假",
];

/** 生成日期 YYYY-MM-DD */
function dateOffset(daysAgo: number): string {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  d.setDate(d.getDate() - daysAgo);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

/** 请假类型轮转 */
const LEAVE_TYPES: LeaveType[] = [
  "SICK",
  "PERSONAL",
  "ANNUAL",
  "SICK",
  "PERSONAL",
  "OTHER",
  "SICK",
  "ANNUAL",
  "PERSONAL",
  "OTHER",
  "SICK",
  "PERSONAL",
  "ANNUAL",
  "SICK",
  "PERSONAL",
];

/** 请假状态轮转 */
const LEAVE_STATUSES: LeaveStatus[] = [
  "PENDING",
  "APPROVED",
  "REJECTED",
  "APPROVED",
  "PENDING",
  "APPROVED",
  "REJECTED",
  "PENDING",
  "APPROVED",
  "APPROVED",
  "PENDING",
  "APPROVED",
  "REJECTED",
  "PENDING",
  "APPROVED",
];

/** 生成 15 条请假申请 */
function generateLeaveRequests(): LeaveRequest[] {
  const list: LeaveRequest[] = [];
  for (let i = 0; i < 15; i++) {
    const teacher = TEACHERS[i % TEACHERS.length];
    if (!teacher) continue;
    const type = LEAVE_TYPES[i] ?? "PERSONAL";
    const status = LEAVE_STATUSES[i] ?? "PENDING";
    const submittedAt = dateOffset(15 - i);
    const startDate = dateOffset(13 - i);
    const endDate = dateOffset(12 - i);
    const reason = LEAVE_REASONS[i % LEAVE_REASONS.length] ?? "个人事务";
    const reviewed =
      status === "PENDING"
        ? null
        : {
            reviewedAt: dateOffset(14 - i),
            reviewerId: REVIEWER.id,
            reviewerName: REVIEWER.name,
            reviewComment:
              status === "APPROVED" ? "已批准" : "理由不充分，请补充材料",
          };
    list.push({
      id: `lr-2026-${String(i + 1).padStart(3, "0")}`,
      applicantId: teacher.id,
      applicantName: teacher.name,
      applicantRole: teacher.role,
      type,
      startDate,
      endDate,
      reason,
      status,
      submittedAt,
      reviewedAt: reviewed?.reviewedAt ?? null,
      reviewerId: reviewed?.reviewerId ?? null,
      reviewerName: reviewed?.reviewerName ?? null,
      reviewComment: reviewed?.reviewComment ?? null,
    });
  }
  return list;
}

/** 全量请假申请缓存 */
const ALL_LEAVE_REQUESTS: LeaveRequest[] = generateLeaveRequests();

/** 保存的请假覆盖（按 requestId 索引） */
const LEAVE_OVERRIDES = new Map<string, LeaveRequest>();

/** 应用覆盖后的请假申请读取 */
function resolveLeave(id: string): LeaveRequest | undefined {
  const override = LEAVE_OVERRIDES.get(id);
  if (override) return override;
  return ALL_LEAVE_REQUESTS.find((r) => r.id === id);
}

/** 请假列表查询 */
export function queryLeaveRequests(
  filter: LeaveRequestsFilter,
): LeaveRequestsResult {
  const { dataScope, status, page, pageSize } = filter;
  const safePage = page ?? 1;
  const safePageSize = pageSize ?? 50;
  // 应用覆盖后的列表
  const merged = ALL_LEAVE_REQUESTS.map(
    (r) => LEAVE_OVERRIDES.get(r.id) ?? r,
  );
  const filtered = merged.filter((r) => {
    if (status && r.status !== status) return false;
    // dataScope 过滤：SELF 只看自己的（mock 里全部 teacher 角色，模拟当前教师 = u-001）
    if (dataScope === "SELF" && r.applicantId !== "u-001") return false;
    return true;
  });
  const total = filtered.length;
  const totalPages = Math.max(1, Math.ceil(total / safePageSize));
  const currentPage = Math.min(Math.max(1, safePage), totalPages);
  const start = (currentPage - 1) * safePageSize;
  const items = filtered.slice(start, start + safePageSize);
  return { items, total, page: currentPage, pageSize: safePageSize };
}

/** 审批请假 */
export function approveLeaveRequest(
  input: ApproveLeaveRequestInput,
): ApproveLeaveRequestResult {
  const original = resolveLeave(input.requestId);
  const newStatus: LeaveStatus =
    input.action === "APPROVE" ? "APPROVED" : "REJECTED";
  const now = new Date().toISOString();
  const updated: LeaveRequest = {
    ...(original ?? {
      id: input.requestId,
      applicantId: "unknown",
      applicantName: "未知",
      applicantRole: "teacher",
      type: "PERSONAL" as LeaveType,
      startDate: "",
      endDate: "",
      reason: "",
      status: "PENDING",
      submittedAt: now,
      reviewedAt: null,
      reviewerId: null,
      reviewerName: null,
      reviewComment: null,
    }),
    status: newStatus,
    reviewedAt: now,
    reviewerId: REVIEWER.id,
    reviewerName: REVIEWER.name,
    reviewComment: input.comment ?? null,
  };
  LEAVE_OVERRIDES.set(input.requestId, updated);
  return {
    requestId: input.requestId,
    status: newStatus,
    reviewedAt: now,
    reviewerId: REVIEWER.id,
    reviewerName: REVIEWER.name,
    reviewComment: input.comment ?? null,
  };
}

/** 提交请假申请 */
export function submitLeaveRequest(
  input: SubmitLeaveRequestInput,
): SubmitLeaveRequestResult {
  const now = new Date().toISOString();
  const seq = String(ALL_LEAVE_REQUESTS.length + LEAVE_OVERRIDES.size + 1).padStart(
    3,
    "0",
  );
  const requestId = `lr-2026-${seq}`;
  const newRequest: LeaveRequest = {
    id: requestId,
    applicantId: "u-001",
    applicantName: "王老师",
    applicantRole: "teacher",
    type: input.type,
    startDate: input.startDate,
    endDate: input.endDate,
    reason: input.reason,
    status: "PENDING",
    submittedAt: now,
    reviewedAt: null,
    reviewerId: null,
    reviewerName: null,
    reviewComment: null,
  };
  LEAVE_OVERRIDES.set(requestId, newRequest);
  return {
    requestId,
    status: "PENDING",
    submittedAt: now,
  };
}

// ============ 调课申请 ============

/** 调课原因模板 */
const CHANGE_REASONS = [
  "出差需调课",
  "请同事代课",
  "教务临时调整",
  "学科组活动",
  "家中有事",
  "培训冲突",
  "会议冲突",
  "外出学习",
  "代同事上课",
  "校际教研",
];

/** 调课类型轮转 */
const CHANGE_TYPES: ScheduleChangeType[] = [
  "ADJUST",
  "SUBSTITUTE",
  "ADJUST",
  "ADJUST",
  "SUBSTITUTE",
  "ADJUST",
  "SUBSTITUTE",
  "ADJUST",
  "SUBSTITUTE",
  "ADJUST",
];

/** 调课状态轮转 */
const CHANGE_STATUSES: ScheduleChangeStatus[] = [
  "PENDING",
  "APPROVED",
  "REJECTED",
  "APPROVED",
  "PENDING",
  "APPROVED",
  "PENDING",
  "APPROVED",
  "REJECTED",
  "PENDING",
];

/** 生成 10 条调课申请 */
function generateScheduleChanges(): ScheduleChange[] {
  const list: ScheduleChange[] = [];
  for (let i = 0; i < 10; i++) {
    const teacher = TEACHERS[i % TEACHERS.length];
    if (!teacher) continue;
    const cls = EXTENDED_CLASSES[i % EXTENDED_CLASSES.length];
    if (!cls) continue;
    const subject = SUBJECTS[i % SUBJECTS.length] ?? "数学";
    const type = CHANGE_TYPES[i] ?? "ADJUST";
    const status = CHANGE_STATUSES[i] ?? "PENDING";
    const submittedAt = dateOffset(10 - i);
    const originalDate = dateOffset(8 - i);
    const adjustedDate = dateOffset(6 - i);
    const reason = CHANGE_REASONS[i % CHANGE_REASONS.length] ?? "调课";
    const substitute =
      type === "SUBSTITUTE"
        ? {
            substituteTeacherId: TEACHERS[(i + 1) % TEACHERS.length]?.id ?? null,
            substituteTeacherName:
              TEACHERS[(i + 1) % TEACHERS.length]?.name ?? null,
          }
        : { substituteTeacherId: null, substituteTeacherName: null };
    const reviewed =
      status === "PENDING"
        ? null
        : {
            reviewedAt: dateOffset(9 - i),
            reviewComment:
              status === "APPROVED" ? "已批准" : "原因不充分，请重新提交",
          };
    list.push({
      id: `sc-2026-${String(i + 1).padStart(3, "0")}`,
      requesterId: teacher.id,
      requesterName: teacher.name,
      classId: cls.id,
      className: cls.name,
      originalDate,
      originalPeriod: (i % 8) + 1,
      originalSubject: subject,
      adjustedDate,
      adjustedPeriod: ((i + 2) % 8) + 1,
      adjustedSubject: subject,
      substituteTeacherId: substitute.substituteTeacherId,
      substituteTeacherName: substitute.substituteTeacherName,
      type,
      reason,
      status,
      submittedAt,
      reviewedAt: reviewed?.reviewedAt ?? null,
      reviewComment: reviewed?.reviewComment ?? null,
    });
  }
  return list;
}

/** 全量调课申请缓存 */
const ALL_SCHEDULE_CHANGES: ScheduleChange[] = generateScheduleChanges();

/** 保存的调课覆盖（按 requestId 索引） */
const CHANGE_OVERRIDES = new Map<string, ScheduleChange>();

/** 调课列表查询 */
export function queryScheduleChanges(
  page = 1,
  pageSize = 50,
): ScheduleChangesResult {
  const merged = ALL_SCHEDULE_CHANGES.map(
    (r) => CHANGE_OVERRIDES.get(r.id) ?? r,
  );
  const total = merged.length;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  const currentPage = Math.min(Math.max(1, page), totalPages);
  const start = (currentPage - 1) * pageSize;
  const items = merged.slice(start, start + pageSize);
  return { items, total, page: currentPage, pageSize };
}

/** 提交调课申请 */
export function submitScheduleChange(
  input: SubmitScheduleChangeInput,
): SubmitScheduleChangeResult {
  const now = new Date().toISOString();
  const seq = String(
    ALL_SCHEDULE_CHANGES.length + CHANGE_OVERRIDES.size + 1,
  ).padStart(3, "0");
  const requestId = `sc-2026-${seq}`;
  const cls = EXTENDED_CLASSES.find((c) => c.id === input.classId);
  const newRequest: ScheduleChange = {
    id: requestId,
    requesterId: "u-001",
    requesterName: "王老师",
    classId: input.classId,
    className: cls?.name ?? "未知班级",
    originalDate: input.originalDate,
    originalPeriod: input.originalPeriod,
    originalSubject: input.originalSubject,
    adjustedDate: input.adjustedDate,
    adjustedPeriod: input.adjustedPeriod,
    adjustedSubject: input.adjustedSubject,
    substituteTeacherId: input.substituteTeacherId ?? null,
    substituteTeacherName: null,
    type: input.type,
    reason: input.reason,
    status: "PENDING",
    submittedAt: now,
    reviewedAt: null,
    reviewComment: null,
  };
  CHANGE_OVERRIDES.set(requestId, newRequest);
  return {
    requestId,
    status: "PENDING",
    submittedAt: now,
  };
}

/** 当前教师可访问的 dataScope 列表（用于 UI 下拉） */
export const DATA_SCOPES: Array<{ value: DataScope; label: string }> = [
  { value: "SELF", label: "我的申请" },
  { value: "CLASS", label: "本班" },
  { value: "GRADE", label: "本年级" },
  { value: "SCHOOL", label: "全校" },
];

/** 请假类型映射 */
export const LEAVE_TYPE_LABEL: Record<LeaveType, string> = {
  SICK: "病假",
  PERSONAL: "事假",
  ANNUAL: "年假",
  OTHER: "其他",
};

/** 请假状态映射 */
export const LEAVE_STATUS_LABEL: Record<LeaveStatus, string> = {
  PENDING: "待审批",
  APPROVED: "已批准",
  REJECTED: "已拒绝",
};

/** 调课类型映射 */
export const SCHEDULE_CHANGE_TYPE_LABEL: Record<ScheduleChangeType, string> = {
  ADJUST: "调课",
  SUBSTITUTE: "代课",
};

/** 调课状态映射 */
export const SCHEDULE_CHANGE_STATUS_LABEL: Record<ScheduleChangeStatus, string> =
  {
    PENDING: "待审批",
    APPROVED: "已批准",
    REJECTED: "已拒绝",
  };
