/**
 * 考勤模块服务接口抽象。
 *
 * 设计目标（P1-12 / P2-6）：
 * - 通过 TypeScript 接口抽象数据依赖，使用 React Context 注入数据服务。
 * - 模块内部组件绝不直接 import 其他业务模块的 actions 或 data-access，
 *   只能通过注入的接口调用。
 * - 不同角色的差异通过接口的不同实现来隔离。
 * - 导出清晰的接口类型以便 mock（可测试性）。
 *
 * 使用方式：
 * - Server Component：通过 `createAttendanceDataService(scope)` 获取实现，
 *   以接口类型 `AttendanceDataService` 消费。
 * - Client Component：通过 `<AttendanceProvider service={...}>` 注入，
 *   内部用 `useAttendanceService()` 读取。
 */
import type { DataScope } from "@/shared/types/permissions"

import type {
  AttendanceListItem,
  AttendanceQueryParams,
  AttendanceRule,
  AttendanceStats,
  ClassAttendanceSummary,
  PaginatedAttendanceResult,
  StudentAttendanceSummary,
} from "../types"
import type {
  AttendanceRuleInput,
  BatchRecordAttendanceInput,
  RecordAttendanceInput,
  UpdateAttendanceInput,
} from "../schema"

/** 日期范围参数。 */
export interface DateRange {
  startDate?: string
  endDate?: string
}

/**
 * 考勤数据读取服务接口（查询契约）。
 * 消费方（parent / student / 其他模块）依赖此接口，不依赖具体 data-access 实现。
 */
export interface AttendanceReadService {
  /** 获取学生考勤汇总（统计 + 最近记录）。 */
  getStudentSummary(
    studentId: string,
    range?: DateRange,
    recentLimit?: number,
  ): Promise<StudentAttendanceSummary | null>

  /** 获取学生最近考勤记录。 */
  getRecentRecords(
    studentId: string,
    limit: number,
  ): Promise<AttendanceListItem[]>

  /** 按日期获取班级考勤记录（点名场景）。 */
  getClassRecordsForDate(
    classId: string,
    date: string,
  ): Promise<AttendanceListItem[]>

  /** 获取班级考勤统计。 */
  getClassStats(
    classId: string,
    range?: DateRange,
  ): Promise<ClassAttendanceSummary | null>

  /** 分页查询考勤记录（admin/teacher 列表场景）。 */
  queryRecords(
    params: AttendanceQueryParams & { scope: DataScope; currentUserId?: string },
  ): Promise<PaginatedAttendanceResult>

  /** 获取考勤总览统计（admin/teacher 仪表盘）。 */
  getOverviewStats(params: {
    scope: DataScope
    currentUserId: string
    classId?: string
    date?: string
  }): Promise<AttendanceStats>

  /** 获取班级考勤规则。 */
  getRules(classId?: string): Promise<AttendanceRule[]>
}

/**
 * 考勤数据写入服务接口（命令契约）。
 * 仅教师/管理员角色实现；学生/家长角色不实现此接口（无写权限）。
 */
export interface AttendanceWriteService {
  /** 创建单条考勤记录。 */
  recordAttendance(
    data: RecordAttendanceInput,
    recordedBy: string,
  ): Promise<string>

  /** 批量创建考勤记录（点名）。 */
  batchRecordAttendance(
    data: BatchRecordAttendanceInput,
    recordedBy: string,
  ): Promise<number>

  /** 更新考勤记录。 */
  updateAttendance(id: string, data: UpdateAttendanceInput): Promise<void>

  /** 删除考勤记录。 */
  deleteAttendance(id: string): Promise<void>

  /** 保存（upsert）考勤规则。 */
  saveRules(data: AttendanceRuleInput): Promise<string>
}

/**
 * 完整的考勤数据服务接口（读 + 写）。
 * 教师与管理员角色使用此接口；学生/家长仅使用 `AttendanceReadService`。
 */
export interface AttendanceDataService
  extends AttendanceReadService,
    AttendanceWriteService {}

/**
 * 考勤 Repository 接口（P2-6）。
 * 仅供 data-access 层实现与测试 mock 使用，定义底层 CRUD 契约。
 */
export interface AttendanceRepository {
  findRecords(
    params: AttendanceQueryParams & { scope: DataScope; currentUserId?: string },
  ): Promise<PaginatedAttendanceResult>
  findClassRecordsForDate(
    classId: string,
    date: string,
  ): Promise<AttendanceListItem[]>
  findRecordClassId(id: string): Promise<string | null>
  createRecord(
    data: RecordAttendanceInput,
    recordedBy: string,
  ): Promise<string>
  batchCreateRecords(
    data: BatchRecordAttendanceInput,
    recordedBy: string,
  ): Promise<number>
  updateRecord(id: string, data: UpdateAttendanceInput): Promise<void>
  deleteRecord(id: string): Promise<void>
  findRules(classId?: string): Promise<AttendanceRule[]>
  upsertRules(data: AttendanceRuleInput): Promise<string>
}

/**
 * 考勤纯计算服务接口（可测试性：纯逻辑与 UI 分离）。
 * 实现见 `data-access-stats.ts` 的 `computeStats`。
 */
export interface AttendanceStatsCalculator {
  /** 根据记录行计算统计。 */
  computeStats(rows: { status: string }[]): AttendanceStats
}
