// Company documents (Job Registrar Stage 1 / Stage 2 packs) — 2026-11-10. See company-documents.service.ts.
import { Body, Controller, Get, Param, ParseIntPipe, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import type { Response } from 'express';
import * as fs from 'fs';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { CompanyDocumentsService } from './company-documents.service';
import type { GenerateBody } from './company-documents.service';
import { CompanyJobsService } from './company-jobs.service';
import type { CreateJobsBody } from './company-jobs.service';

@Controller('company-documents')
@UseGuards(JwtAuthGuard)
export class CompanyDocumentsController {
  constructor(
    private readonly svc: CompanyDocumentsService,
    private readonly jobs: CompanyJobsService, // 2026-11-10: scheme-style Create Job flow
  ) {}

  private uid(req: any): number {
    return Number(req.user?.id ?? req.user?.userId ?? req.user?.sub);
  }

  /** 2026-11-10 — GET /api/company-documents/access : { view, stages[] } from the dynamic Job Documents permissions */
  @Get('access')
  access(@Req() req: any) {
    return this.jobs.access(this.uid(req));
  }

  // ───────── 2026-11-11: Transfer audits to a Job Documents user (admins / coordinators) ─────────
  // These static routes must stay ABOVE the ':companyId' routes.

  /** GET /api/company-documents/transfer/users */
  @Get('transfer/users')
  transferUsers(@Req() req: any) {
    return this.jobs.transferUsers(this.uid(req));
  }

  /** GET /api/company-documents/transfer/preview?month=2026-08&type=INITIAL|ALL */
  @Get('transfer/preview')
  transferPreview(@Query('month') month: string, @Query('type') type: string, @Req() req: any) {
    return this.jobs.transferPreview(this.uid(req), month, type);
  }

  /** GET /api/company-documents/transfer/summary */
  @Get('transfer/summary')
  transferSummary(@Req() req: any) {
    return this.jobs.transferSummary(this.uid(req));
  }

  /** GET /api/company-documents/transfer/mine — banner for the logged-in user */
  @Get('transfer/mine')
  myTransfers(@Req() req: any) {
    return this.jobs.myTransfers(this.uid(req));
  }

  /** POST /api/company-documents/transfer  { toUserId, rowIds[], note? } */
  @Post('transfer')
  transfer(@Body() body: { toUserId: number; rowIds: number[]; note?: string }, @Req() req: any) {
    return this.jobs.transfer(this.uid(req), body);
  }

  /** POST /api/company-documents/transfer/remove  { rowIds[] } */
  @Post('transfer/remove')
  untransfer(@Body() body: { rowIds: number[] }, @Req() req: any) {
    return this.jobs.untransfer(this.uid(req), body);
  }

  /** GET /api/company-documents/codebook?q=  — NACE / EAC picker */
  @Get('codebook')
  codebook(@Query('q') q: string) {
    return this.svc.codebook(q);
  }

  // ───────── 2026-11-10: scheme-style "Create Job" flow ─────────

  /** GET /api/company-documents/jobs/:jobId/pdf — job document, generated on the fly */
  @Get('jobs/:jobId/pdf')
  async jobPdf(
    @Param('jobId', ParseIntPipe) jobId: number,
    @Query('download') download: string,
    @Req() req: any,
    @Res() res: Response,
  ) {
    const { buf, name } = await this.jobs.jobPdf(jobId, this.uid(req));
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `${download ? 'attachment' : 'inline'}; filename="${name.replace(/"/g, '')}"`);
    res.setHeader('Content-Length', String(buf.length));
    res.end(buf);
  }

  /** GET /api/company-documents/jobs/:jobId/docx — Word copy of the job document (2026-11-10) */
  @Get('jobs/:jobId/docx')
  async jobDocx(@Param('jobId', ParseIntPipe) jobId: number, @Req() req: any, @Res() res: Response) {
    const { buf, name } = await this.jobs.jobDocx(jobId, this.uid(req));
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    res.setHeader('Content-Disposition', `attachment; filename="${name.replace(/"/g, '')}"`);
    res.setHeader('Content-Length', String(buf.length));
    res.end(buf);
  }

  /** GET /api/company-documents/:companyId/job-form — data for the Create Job form */
  @Get(':companyId/job-form')
  jobForm(@Param('companyId', ParseIntPipe) companyId: number, @Req() req: any) {
    return this.jobs.formData(companyId, this.uid(req));
  }

  /** GET /api/company-documents/:companyId/jobs — the company's jobs (Documents tab) */
  @Get(':companyId/jobs')
  companyJobs(@Param('companyId', ParseIntPipe) companyId: number, @Req() req: any) {
    return this.jobs.listForCompany(companyId, this.uid(req));
  }

  /** GET /api/company-documents/:companyId/jobs/zip?stage=Stage 1 — "Download All" */
  @Get(':companyId/jobs/zip')
  async zip(
    @Param('companyId', ParseIntPipe) companyId: number,
    @Query('stage') stage: string,
    @Query('format') format: string,
    @Req() req: any,
    @Res() res: Response,
  ) {
    await this.jobs.zipStage(companyId, stage, this.uid(req), res, format === 'docx' ? 'docx' : 'pdf');
  }

  /** POST /api/company-documents/:companyId/jobs — one job per ticked template */
  @Post(':companyId/jobs')
  createJobs(@Param('companyId', ParseIntPipe) companyId: number, @Body() body: CreateJobsBody, @Req() req: any) {
    return this.jobs.createJobs(companyId, body, this.uid(req));
  }

  /** GET /api/company-documents/packs/:packId — status (polled while generating) */
  @Get('packs/:packId')
  pack(@Param('packId', ParseIntPipe) packId: number, @Req() req: any) {
    return this.svc.getPackForUser(packId, this.uid(req));
  }

  /** GET /api/company-documents/packs/:packId/file/:which  (which = form key, or "zip") */
  @Get('packs/:packId/file/:which')
  async file(
    @Param('packId', ParseIntPipe) packId: number,
    @Param('which') which: string,
    @Query('download') download: string,
    @Req() req: any,
    @Res() res: Response,
  ) {
    const f = await this.svc.filePath(packId, which, this.uid(req));
    res.setHeader('Content-Type', f.type);
    res.setHeader(
      'Content-Disposition',
      `${download || f.type === 'application/zip' ? 'attachment' : 'inline'}; filename="${f.name.replace(/"/g, '')}"`,
    );
    res.setHeader('Content-Length', String(fs.statSync(f.abs).size));
    fs.createReadStream(f.abs).pipe(res);
  }

  /** GET /api/company-documents/:companyId — audits (with prefill), form catalogue and existing packs */
  @Get(':companyId')
  audits(@Param('companyId', ParseIntPipe) companyId: number, @Req() req: any) {
    return this.svc.listAudits(companyId, this.uid(req));
  }

  /** GET /api/company-documents/:companyId/packs */
  @Get(':companyId/packs')
  packs(@Param('companyId', ParseIntPipe) companyId: number, @Req() req: any) {
    return this.svc.listPacks(companyId, this.uid(req));
  }

  /** POST /api/company-documents/:companyId/generate */
  @Post(':companyId/generate')
  generate(@Param('companyId', ParseIntPipe) companyId: number, @Body() body: GenerateBody, @Req() req: any) {
    return this.svc.generate(companyId, body, this.uid(req));
  }
}
