import { BadRequestException, Controller, Get, NotFoundException, Param, ParseIntPipe, Req, Res, UseGuards } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import type { Response } from 'express';

import { JwtAuthGuard } from './../../auth/guards/jwt-auth.guard';
import { AuditReportStorageService } from '../../audit-schedules/services/audit-report-storage.service';

function getCompanyIds(req: any): number[] {
  const ids: number[] = (req.user as any)?.company_ids ?? [];
  if (!ids.length) throw new BadRequestException('No company access found');
  return ids.map(Number);
}

/** Client portal: only APPROVED / LOCKED reports of the client's own audits. Same prefix and id scheme as the checklist client API. */
@Controller('client-portal')
@UseGuards(JwtAuthGuard)
export class ClientAuditReportController {
  constructor(
    @InjectDataSource('scheme_dbs') private readonly db: DataSource,
    private readonly storage: AuditReportStorageService,
  ) {}

  private async myRequest(auditRequestId: number, req: any) {
    const [ar] = await this.db.query(
      `SELECT id, company_id, audit_schedule_row_id FROM audit_requests WHERE id = ? LIMIT 1`,
      [auditRequestId],
    );
    if (!ar || !getCompanyIds(req).includes(Number(ar.company_id)) || !ar.audit_schedule_row_id) {
      throw new NotFoundException('Audit not found');
    }
    return ar;
  }

  @Get('audits/:auditRequestId/reports')
  async list(@Param('auditRequestId', ParseIntPipe) auditRequestId: number, @Req() req: any) {
    const ar = await this.myRequest(auditRequestId, req);
    return this.db.query(
      `SELECT a.id, a.report_no, a.standard_id, a.stage_type, a.version, a.approved_at
         FROM audit_reports a INNER JOIN audit_schedule_rows w ON w.id = a.audit_schedule_row_id
        WHERE a.audit_schedule_row_id = ? AND a.status IN ('approved','locked') AND a.pdf_path IS NOT NULL
          AND w.report_qaqc_approved = 1
        ORDER BY a.approved_at DESC`,
      [ar.audit_schedule_row_id],
    );
  }

  @Get('audits/:auditRequestId/reports/:reportId/pdf')
  async pdf(
    @Param('auditRequestId', ParseIntPipe) auditRequestId: number,
    @Param('reportId', ParseIntPipe) reportId: number,
    @Req() req: any,
    @Res() res: Response,
  ) {
    const ar = await this.myRequest(auditRequestId, req);
    const [r] = await this.db.query(
      `SELECT a.id, a.report_no, a.version, a.pdf_path FROM audit_reports a
         INNER JOIN audit_schedule_rows w ON w.id = a.audit_schedule_row_id
        WHERE a.id = ? AND a.audit_schedule_row_id = ? AND a.status IN ('approved','locked') AND a.pdf_path IS NOT NULL
          AND w.report_qaqc_approved = 1 LIMIT 1`,
      [reportId, ar.audit_schedule_row_id],
    );
    if (!r) throw new NotFoundException('Report not found');
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `inline; filename="${r.report_no}-v${r.version}.pdf"`);
    const f = await this.storage.openFile(r.pdf_path);
    res.setHeader('Content-Length', String(f.size));
    f.stream.pipe(res);
  }
}
