import {
  Controller,
  Get,
  Post,
  Query,
  Req,
  Res,
  BadRequestException,
} from '@nestjs/common';
import type { Request, Response } from 'express';
import { ReportService, ReportType } from './report.service';
import { ExcelService } from './excel.service';
import { ReportScheduler } from './report.scheduler';

@Controller('report')
export class ReportController {
  constructor(
    private readonly reportService: ReportService,
    private readonly excel: ExcelService,
    private readonly scheduler: ReportScheduler,
  ) {}

  private parse(year?: string, month?: string) {
    const now = new Date();
    const y = year ? Number(year) : now.getFullYear();
    const m = month ? Number(month) : now.getMonth() + 1;
    if (!Number.isInteger(y) || !Number.isInteger(m) || m < 1 || m > 12) {
      throw new BadRequestException('Invalid year/month');
    }
    return { y, m };
  }

  /** Validates the optional ?type= param; anything unknown falls back to 'all'. */
  private parseType(type?: string): ReportType {
    const allowed: ReportType[] = ['all', 'recert', 'surv_1', 'surv_11'];
    return allowed.includes(type as ReportType) ? (type as ReportType) : 'all';
  }

  private currentUserId(req: Request): number {
    const user = (req as any).user;
    const id = user?.id ?? user?.userId ?? user?.sub;
    return Number(id ?? process.env.REPORT_SENDER_USER_ID ?? 1);
  }

  /** GET /report/counts?year=2026&month=8&type=recert — live preview in the modal */
  @Get('counts')
  async counts(
    @Query('year') year?: string,
    @Query('month') month?: string,
    @Query('type') type?: string,
  ) {
    const { y, m } = this.parse(year, month);
    const report = await this.reportService.buildReport(y, m, this.parseType(type));
    return {
      month: `${report.monthName} ${report.year}`,
      total: report.total,
      buckets: report.buckets.map((b) => ({ key: b.key, label: b.label, count: b.count })),
    };
  }

  /** GET /report/excel?year=2026&month=8&type=all */
  @Get('excel')
  async download(
    @Res() res: Response,
    @Query('year') year?: string,
    @Query('month') month?: string,
    @Query('type') type?: string,
  ) {
    const { y, m } = this.parse(year, month);
    const report = await this.reportService.buildReport(y, m, this.parseType(type));
    const buffer = await this.excel.build(report);
    res.set({
      'Content-Type':
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename="Certification_Report_${report.monthName}_${report.year}.xlsx"`,
    });
    res.send(buffer);
  }

  /**
   * POST /report/send?year=2026&month=8&type=recert&to=boss@x.com,manager@x.com
   * `to` is the recipient typed in the UI. If omitted, falls back to .env.
   */
  @Post('send')
  async send(
    @Req() req: Request,
    @Query('year') year?: string,
    @Query('month') month?: string,
    @Query('to') to?: string,
    @Query('type') type?: string,
  ) {
    const { y, m } = this.parse(year, month);
    const senderUserId = this.currentUserId(req);
    const { total } = await this.scheduler.runAndSend(
      y,
      m,
      senderUserId,
      to,
      this.parseType(type),
    );
    return { ok: true, message: `Report for ${m}/${y} emailed (${total} certificates).` };
  }
}