import "server-only"

import type { DataScope } from "@/shared/types/permissions"

import {
  batchCreateAttendanceRecords,
  createAttendanceRecord,
  deleteAttendanceRecord,
  getAttendanceRecords,
  getAttendanceRules,
  getAttendanceStats,
  getClassAttendanceForDate,
  upsertAttendanceRules,
  updateAttendanceRecord,
} from "../data-access"
import {
  getClassAttendanceStats,
  getStudentAttendanceSummary,
} from "../data-access-stats"
import type {
  AttendanceDataService,
  AttendanceReadService,
  AttendanceWriteService,
  DateRange,
} from "./types"

/**
 * 基于真实 data-access 的考勤数据服务实现（读操作）。
 * 各角色共用此实现，差异由调用方传入的 `scope` 隔离。
 */
class AttendanceReadServiceImpl implements AttendanceReadService {
  async getStudentSummary(
    studentId: string,
    range?: DateRange,
    recentLimit?: number,
  ) {
    return getStudentAttendanceSummary(
      studentId,
      range?.startDate,
      range?.endDate,
      recentLimit,
    )
  }

  async getRecentRecords(studentId: string, limit: number) {
    const result = await getStudentAttendanceSummary(studentId, undefined, undefined, limit)
    return result?.recentRecords ?? []
  }

  async getClassRecordsForDate(classId: string, date: string) {
    return getClassAttendanceForDate(classId, date)
  }

  async getClassStats(classId: string, range?: DateRange) {
    return getClassAttendanceStats(classId, range?.startDate, range?.endDate)
  }

  async queryRecords(params: Parameters<AttendanceReadService["queryRecords"]>[0]) {
    return getAttendanceRecords(params)
  }

  async getOverviewStats(params: Parameters<AttendanceReadService["getOverviewStats"]>[0]) {
    return getAttendanceStats(params)
  }

  async getRules(classId?: string) {
    return getAttendanceRules(classId)
  }
}

/**
 * 基于真实 data-access 的考勤数据服务实现（写操作）。
 * 仅教师/管理员角色使用；学生/家长不应调用。
 */
class AttendanceWriteServiceImpl implements AttendanceWriteService {
  async recordAttendance(data: Parameters<AttendanceWriteService["recordAttendance"]>[0], recordedBy: string) {
    return createAttendanceRecord(data, recordedBy)
  }

  async batchRecordAttendance(data: Parameters<AttendanceWriteService["batchRecordAttendance"]>[0], recordedBy: string) {
    return batchCreateAttendanceRecords(data, recordedBy)
  }

  async updateAttendance(id: string, data: Parameters<AttendanceWriteService["updateAttendance"]>[1]) {
    return updateAttendanceRecord(id, data)
  }

  async deleteAttendance(id: string) {
    return deleteAttendanceRecord(id)
  }

  async saveRules(data: Parameters<AttendanceWriteService["saveRules"]>[0]) {
    return upsertAttendanceRules(data)
  }
}

/**
 * 完整的考勤数据服务实现（读 + 写）。
 * data-access 层函数的薄封装，统一接口契约。
 */
class AttendanceDataServiceImpl
  implements AttendanceDataService
{
  private readonly reader = new AttendanceReadServiceImpl()
  private readonly writer = new AttendanceWriteServiceImpl()

  getStudentSummary = this.reader.getStudentSummary.bind(this.reader)
  getRecentRecords = this.reader.getRecentRecords.bind(this.reader)
  getClassRecordsForDate = this.reader.getClassRecordsForDate.bind(this.reader)
  getClassStats = this.reader.getClassStats.bind(this.reader)
  queryRecords = this.reader.queryRecords.bind(this.reader)
  getOverviewStats = this.reader.getOverviewStats.bind(this.reader)
  getRules = this.reader.getRules.bind(this.reader)

  recordAttendance = this.writer.recordAttendance.bind(this.writer)
  batchRecordAttendance = this.writer.batchRecordAttendance.bind(this.writer)
  updateAttendance = this.writer.updateAttendance.bind(this.writer)
  deleteAttendance = this.writer.deleteAttendance.bind(this.writer)
  saveRules = this.writer.saveRules.bind(this.writer)
}

/** 单例实例（无状态，可安全共享）。 */
const sharedService = new AttendanceDataServiceImpl()

/**
 * 获取考勤数据服务实例。
 *
 * Server Component 调用此工厂以接口类型 `AttendanceDataService` 消费，
 * 避免直接 import data-access 函数（P1-12 修复）。
 *
 * @param _scope 当前用户的数据范围（用于文档化角色差异；实际过滤由 data-access 内 buildScopeFilter 执行）
 */
export function createAttendanceDataService(
  _scope?: DataScope,
): AttendanceDataService {
  // 当前实现无状态且共享；scope 在具体 data-access 调用时传入。
  // 未来若需按角色返回不同实现，可在此分支。
  return sharedService
}

/**
 * 获取只读考勤数据服务（学生/家长角色使用）。
 * 返回的接口不包含写操作，编译期即阻止误用。
 */
export function createAttendanceReadService(
  _scope?: DataScope,
): AttendanceReadService {
  return sharedService
}

// 重新导出常用类型，便于消费方单点导入
export type {
  AttendanceDataService,
  AttendanceReadService,
  AttendanceWriteService,
  DateRange,
} from "./types"

// 暴露 getAttendanceRecordClassId（归属校验所需，不属于读写服务契约）
export { getAttendanceRecordClassId } from "../data-access"
