import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  Request,
  Res,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import type { Response } from 'express';
import { ClassroomsService } from './classrooms.service';
import { CreateClassroomDto, UpdateClassroomDto } from './dto/classroom.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
import { CLASSROOM_TEMPLATE_COLUMNS } from './classroom-template';

@UseGuards(JwtAuthGuard)
@Controller('classrooms')
export class ClassroomsController {
  constructor(
    private service: ClassroomsService,
    private logService: OperationLogsService,
  ) {}

  @Get()
  @RequirePermission('classroom:view')
  findAll(
    @Query('building') building?: string,
    @Query('roomType') roomType?: string,
    @Query('includeArchived') includeArchived?: string,
  ) {
    return this.service.findAll({
      building,
      roomType,
      includeArchived: includeArchived === 'true',
    });
  }

  @Get('template')
  @RequirePermission('classroom:view')
  async downloadTemplate(@Res() res: Response) {
    const workbook = new ExcelJS.Workbook();
    const ws = workbook.addWorksheet('教室导入模板');
    ws.columns = CLASSROOM_TEMPLATE_COLUMNS;
    ws.getRow(1).font = { bold: true };
    ws.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE0E0E0' } };
    ws.addRow({
      name: 'A201',
      building: 'A座',
      floor: 2,
      roomType: '大',
      capacity: 60,
    });
    ws.addRow({
      name: 'B301',
      building: 'B座',
      floor: 3,
      roomType: '次大',
      capacity: 40,
    });
    ws.addRow({
      name: 'B405',
      building: 'B座',
      floor: 4,
      roomType: '小',
      capacity: 20,
    });

    // 说明sheet
    const ws2 = workbook.addWorksheet('使用说明');
    ws2.columns = [{ header: '说明', key: 'note', width: 80 }];
    ws2.getRow(1).font = { bold: true };
    [
      '1. 教室名必填，建议采用「楼栋+房号」如 A201、B301',
      '2. 类型可填 大 / 次大 / 小，为空默认「大」',
      '3. 同名教室会自动跳过（不覆盖）',
    ].forEach((note) => ws2.addRow({ note }));

    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
    res.setHeader('Content-Disposition', 'attachment; filename=classroom_template.xlsx');
    await workbook.xlsx.write(res);
    res.end();
  }

  @Get(':id')
  @RequirePermission('classroom:view')
  findOne(@Param('id') id: string) {
    return this.service.findOne(+id);
  }

  @Post()
  @RequirePermission('classroom:create')
  async create(@Body() dto: CreateClassroomDto, @Request() req: any) {
    const { ipAddress, userAgent } = extractRequestInfo(req);
    const result = await this.service.create(dto);
    await this.logService.log({
      userId: req.user?.id,
      username: req.user?.username,
      module: '教室',
      action: '新增教室',
      targetId: result.id,
      targetType: 'classroom',
      detail: dto.name,
      ipAddress,
      userAgent,
    });
    return result;
  }

  @Put(':id')
  @RequirePermission('classroom:edit')
  async update(@Param('id') id: string, @Body() dto: UpdateClassroomDto, @Request() req: any) {
    const { ipAddress, userAgent } = extractRequestInfo(req);
    const result = await this.service.update(+id, dto);
    await this.logService.log({
      userId: req.user?.id,
      username: req.user?.username,
      module: '教室',
      action: '编辑教室',
      targetId: +id,
      targetType: 'classroom',
      detail: JSON.stringify(dto),
      ipAddress,
      userAgent,
    });
    return result;
  }

  @Delete(':id')
  @RequirePermission('classroom:delete')
  async remove(@Param('id') id: string, @Request() req: any) {
    const { ipAddress, userAgent } = extractRequestInfo(req);
    const result = await this.service.remove(+id);
    await this.logService.log({
      userId: req.user?.id,
      username: req.user?.username,
      module: '教室',
      action: '归档教室',
      targetId: +id,
      targetType: 'classroom',
      ipAddress,
      userAgent,
    });
    return result;
  }

  @Put(':id/restore')
  @RequirePermission('classroom:edit')
  async restore(@Param('id') id: string, @Request() req: any) {
    const { ipAddress, userAgent } = extractRequestInfo(req);
    const result = await this.service.restore(+id);
    await this.logService.log({
      userId: req.user?.id,
      username: req.user?.username,
      module: '教室',
      action: '恢复教室',
      targetId: +id,
      targetType: 'classroom',
      ipAddress,
      userAgent,
    });
    return result;
  }

  @Post('import')
  @RequirePermission('classroom:create')
  @UseInterceptors(FileInterceptor('file'))
  async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
    const { ipAddress, userAgent } = extractRequestInfo(req);
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.load(file.buffer as any);
    const ws = workbook.worksheets[0];
    const rows: any[] = [];
    ws.eachRow((row, idx) => {
      if (idx === 1) return;
      rows.push({
        name: String(row.getCell(1).value || ''),
        building: String(row.getCell(2).value || '') || undefined,
        floor: Number(row.getCell(3).value) || undefined,
        roomType: String(row.getCell(4).value || '') || undefined,
        capacity: Number(row.getCell(5).value) || undefined,
      });
    });
    const result = await this.service.batchImport(rows);
    await this.logService.log({
      userId: req.user?.id,
      username: req.user?.username,
      module: '教室',
      action: '批量导入',
      detail: result.message,
      ipAddress,
      userAgent,
    });
    return result;
  }

  @Get('report')
  @RequirePermission('classroom:view')
  async exportReport(
    @Query('dateFrom') dateFrom: string,
    @Query('dateTo') dateTo: string,
    @Res() res: Response,
  ) {
    const data = await this.service.getUsageReport(dateFrom, dateTo);
    const workbook = new ExcelJS.Workbook();
    const ws = workbook.addWorksheet('教室使用统计');
    ws.columns = [
      { header: '教室名称', key: 'name', width: 20 },
      { header: '楼栋', key: 'building', width: 12 },
      { header: '类型', key: 'roomType', width: 12 },
      { header: '容量', key: 'capacity', width: 8 },
      { header: '统计天数', key: 'totalDays', width: 10 },
      { header: '租赁占用天数', key: 'rentalDays', width: 14 },
      { header: '排课占用天数', key: 'scheduleDays', width: 14 },
      { header: '空闲天数', key: 'idleDays', width: 10 },
      { header: '占用率', key: 'occupancyRate', width: 10 },
    ];
    ws.getRow(1).font = { bold: true };
    ws.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE0E0E0' } };
    for (const row of data) {
      ws.addRow({ ...row, occupancyRate: `${row.occupancyRate}%` });
    }
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', 'attachment; filename=classroom-report.xlsx');
    await workbook.xlsx.write(res);
    res.end();
  }
 }
