import {
  Controller,
  Get,
  Post,
  Put,
  Body,
  Param,
  Query,
  Request,
  BadRequestException,
  ParseIntPipe,
} from '@nestjs/common';
import { AttendanceControllerBase, RequestUser } from './attendance.controller-base';
import { AttendanceService } from './attendance.service';
import { AttendanceImportService } from './attendance-import.service';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { AuthorizationService } from '../authorization';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import {
  SaveAttendancePeriodConfigsDto,
  LessonAttendanceQueryDto,
  StartLessonAttendanceDto,
} from './dto/attendance.dto';

@Controller()
export class AttendanceController extends AttendanceControllerBase {
  constructor(
    service: AttendanceService,
    importService: AttendanceImportService,
    logService: OperationLogsService,
    authz: AuthorizationService,
  ) {
    super(service, importService, logService, authz);
  }

  @Get('attendance-period-configs')
  @RequirePermission('attendance:view')
  getAttendancePeriodConfigs() {
    return this.service.getAttendancePeriodConfigs();
  }

  @Put('attendance-period-configs')
  @RequirePermission('attendance:edit')
  async saveAttendancePeriodConfigs(
    @Body() dto: SaveAttendancePeriodConfigsDto,
    @Request() req: { user: RequestUser },
  ) {
    const result = await this.service.saveAttendancePeriodConfigs(dto);
    await this.logService.log({
      userId: req.user.id,
      username: req.user.username,
      module: '考勤管理',
      action: '保存考勤时段配置',
      targetType: 'attendancePeriodConfig',
      detail: dto.periods
        .map((item) => `${item.label}:${item.startTime}-${item.endTime}`)
        .join('；'),
    });
    return result;
  }

  @Post('attendance-period-configs/reset')
  @RequirePermission('attendance:edit')
  async resetAttendancePeriodConfigs(@Request() req: { user: RequestUser }) {
    const result = await this.service.resetAttendancePeriodConfigs();
    await this.logService.log({
      userId: req.user.id,
      username: req.user.username,
      module: '考勤管理',
      action: '重置考勤时段配置',
      targetType: 'attendancePeriodConfig',
    });
    return result;
  }

  @Get('attendance-lessons/schedules/:scheduleId')
  @RequirePermission('attendance:view')
  async getLessonAttendance(
    @Param('scheduleId', ParseIntPipe) scheduleId: number,
    @Query() query: LessonAttendanceQueryDto,
    @Request() req: { user: RequestUser },
  ) {
    const result = await this.service.getLessonAttendance(scheduleId, query.date);
    await this.assertClassAccess(req, result.schedule.classId!);
    return result;
  }

  @Post('attendance-lessons/schedules/:scheduleId/pull')
  @RequirePermission('attendance:create')
  async pullLessonAttendance(
    @Param('scheduleId', ParseIntPipe) scheduleId: number,
    @Body() dto: StartLessonAttendanceDto,
    @Request() req: { user: RequestUser },
  ) {
    const schedule = await this.service.getLessonAttendance(scheduleId, dto.date);
    await this.assertClassAccess(req, schedule.schedule.classId!);
    const importClassIds = await this.service.getTeacherClassDingUserIds(
      req.user.id,
      schedule.schedule.classId!,
      this.canManageAllAttendance(req),
      dto.date,
    );
    const importRange = this.service.getLessonAttendanceImportDateRange(
      schedule.schedule,
      dto.date,
    );
    const importResult = await this.importService.importFromDingTalk({
      ...importRange,
      userIds: importClassIds,
      autoMatch: true,
      userId: req.user.id,
    });
    if (!importResult.success || importResult.errors.length > 0) {
      throw new BadRequestException(importResult.errors.join('; ') || '钉钉考勤拉取失败');
    }
    const result = await this.service.createLessonAttendanceFromDingTalk(
      scheduleId,
      dto.date,
      req.user.id,
    );
    await this.logService.log({
      userId: req.user.id,
      username: req.user.username,
      module: '考勤管理',
      action: schedule.session ? '查看已拉取课程考勤' : '拉取钉钉课程考勤',
      targetId: result.session.id,
      targetType: 'attendanceSession',
      detail: `排课${scheduleId} 日期${dto.date}，钉钉新增${importResult.imported}条，匹配${importResult.matched}条`,
    });
    return result;
  }

  @Post('attendance-lessons/:sessionId/complete')
  @RequirePermission('attendance:create')
  async completeLessonAttendance(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Request() req: { user: RequestUser },
  ) {
    const session = await this.service.findAttendanceSession(sessionId);
    await this.assertClassAccess(req, session.classId);
    const result = await this.service.completeLessonAttendance(sessionId, req.user.id);
    await this.logService.log({
      userId: req.user.id,
      username: req.user.username,
      module: '考勤管理',
      action: '完成课程点名',
      targetId: sessionId,
      targetType: 'attendanceSession',
      detail: `班级${session.classId} 日期${session.lessonDate}`,
    });
    return result;
  }

}
