import {
  Controller, Get, Post, Patch, Put, Delete, Param, Body,
  ParseIntPipe, Query, Res,
  UploadedFile, UseInterceptors, BadRequestException,   // ← ADD these three
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';  // ← ADD
import { diskStorage } from 'multer';                          // ← ADD
import { extname } from 'path';                                // ← ADD
import type { Response } from 'express';
import { CertificatesService } from './certificates.service';
import { CreateCertificateDto } from './dto/create-certificate.dto';
import { UpdateCertificateDto } from './dto/update-certificate.dto';
import { NewCertificate } from './entities/new-certificate.entity';
// ✅ NEW — Import the draft generator service
import { CertificateDraftGeneratorService } from './certificate-draft-generator.service';

@Controller('certificates')
export class CertificatesController {
  // ✅ FIXED — Constructor with proper injection of BOTH services
  constructor(
    private readonly service: CertificatesService,
    private readonly certDraftGenerator: CertificateDraftGeneratorService,
  ) { }

  @Post()
  async create(@Body() dto: CreateCertificateDto) {
    const result = await this.service.create(dto);

    // If multiple standards, return all certificates
    if (result.certificates.length > 1) {
      return {
        summary: result.summary,
        certificates: result.certificates.map((c) => ({
          certificate: c.certificate,
          qrCode: c.qrCodeDataUrl,
          verification_url: c.verification_url,
          action: c.action,
          source: c.source,
        })),
      };
    }

    // Single certificate (first element)
    const single = result.certificates[0];
    return {
      certificate: single.certificate,
      qrCode: single.qrCodeDataUrl,
      verification_url: single.verification_url,
      action: single.action,
      source: single.source,
    };
  }

  @Patch(':id')
  async updatePartial(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: Partial<UpdateCertificateDto>,
  ): Promise<NewCertificate> {
    return this.service.updatePartial(id, dto);
  }

  @Put(':id')
  async update(
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: UpdateCertificateDto,
  ): Promise<NewCertificate> {
    return this.service.update(id, dto);
  }

  @Get()
  async findAll(
    @Query('page', new ParseIntPipe({ optional: true })) page = 1,
    @Query('search') search?: string,
  ) {
    const {
      data,
      total,
      page: currentPage,
      lastPage,
    } = await this.service.findAll(page, search);

    const dataWithQr = await Promise.all(
      data.map(async (cert) => ({
        ...cert,
        verification_url: this.service.buildVerificationUrl(cert),
        qrCode: await this.service.generateQrCode(
          cert.qrcode_token,
          cert.fingerprint,
          cert.verification_domain as 'local' | 'international',
        ),
      })),
    );

    return { data: dataWithQr, total, page: currentPage, lastPage };
  }

  @Get('verify')
  async verifyCertificate(
    @Query('token') token: string,
    @Query('fp') fingerprint?: string,
  ) {
    return this.service.verifyCertificate(token, fingerprint);
  }
  @Get('resolve-token')
  async resolveToken(
    @Query('token') token: string,
    @Query('fp') fp?: string,
  ) {
    return this.service.resolveToken(token, fp);
  }
  @Get(':id')
  async findOne(@Param('id', ParseIntPipe) id: number) {
    const certificate = await this.service.findOne(id);

    // generate QR code dynamically
    const qrCode = await this.service.generateQrCode(
      certificate.qrcode_token,
      certificate.fingerprint,
      certificate.verification_domain as 'local' | 'international',
    );

    return {
      certificate,
      verification_url: this.service.buildVerificationUrl(certificate),
      qrCode,
    };
  }

  @Delete(':id')
  async remove(
    @Param('id', ParseIntPipe) id: number,
  ): Promise<{ message: string }> {
    return this.service.remove(id);
  }
// ═══ ADD THIS — upload digital copy ═══
  @Post(':id/digital-copy')
  @UseInterceptors(
    FileInterceptor('digital_copy', {
      storage: diskStorage({
        destination: './uploads/certificate-scans',
        filename: (req, file, cb) =>
          cb(null, `cert-${req.params.id}-${Date.now()}${extname(file.originalname) || '.jpg'}`),
      }),
      limits: { fileSize: 10 * 1024 * 1024 },
      fileFilter: (req, file, cb) => {
        const ok = /image\/(jpe?g|png)|application\/pdf/.test(file.mimetype);
        cb(ok ? null : new BadRequestException('Only JPG, PNG or PDF allowed'), ok);
      },
    }),
  )
  async uploadDigitalCopy(
    @Param('id', ParseIntPipe) id: number,
    @UploadedFile() file: Express.Multer.File,
  ) {
    if (!file) throw new BadRequestException('No file uploaded (field: digital_copy)');
    const base = process.env.PUBLIC_BASE_URL || 'https://crm.qrsyst.com';
    const fileUrl = `${base}/uploads/certificate-scans/${file.filename}`;
    return this.service.attachDigitalCopy(id, fileUrl);
  }
  // ═══════════════════════════════════════════════════════════════════
  // ✅ NEW — DRAFT/CERTIFICATE PDF + WORD GENERATION ENDPOINTS
  // ═══════════════════════════════════════════════════════════════════

  // ── Download PDF (with optional ?draft=true watermark) ────────
  @Get(':id/download/pdf')
  async downloadCertPdf(
    @Param('id', ParseIntPipe) id: number,
    @Query('draft') draft: string,
    @Res() res: Response,
  ) {
    const cert = await this.service.getCertificateForDraft(id);
    if (!cert) {
      return res.status(404).send('Certificate not found');
    }

    const isDraft = draft === 'true' || draft === '1';

    const filePath = await this.certDraftGenerator.generatePdf(cert, {
      draft: isDraft,
    });

    const { buffer, fileName } = this.certDraftGenerator.getFile(filePath);

    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${fileName}"`,
      'Content-Length': buffer.length,
    });

    return res.send(buffer);
  }

  // ── Download Word ─────────────────────────────────────────────
  @Get(':id/download/docx')
  async downloadCertDocx(
    @Param('id', ParseIntPipe) id: number,
    @Res() res: Response,
  ) {
    const cert = await this.service.getCertificateForDraft(id);
    if (!cert) {
      return res.status(404).send('Certificate not found');
    }

    const filePath = await this.certDraftGenerator.generateDocx(cert);
    const { buffer, fileName } = this.certDraftGenerator.getFile(filePath);

    res.set({
      'Content-Type':
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'Content-Disposition': `attachment; filename="${fileName}"`,
      'Content-Length': buffer.length,
    });

    return res.send(buffer);
  }

  // ── Preview PDF in browser (no download) ──────────────────────
  @Get(':id/preview/pdf')
  async previewCertPdf(
    @Param('id', ParseIntPipe) id: number,
    @Query('draft') draft: string,
    @Res() res: Response,
  ) {
    const cert = await this.service.getCertificateForDraft(id);
    if (!cert) {
      return res.status(404).send('Certificate not found');
    }

    const isDraft = draft === 'true' || draft === '1';
    const filePath = await this.certDraftGenerator.generatePdf(cert, {
      draft: isDraft,
    });

    const { buffer } = this.certDraftGenerator.getFile(filePath);

    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'inline',
      'Content-Length': buffer.length,
    });

    return res.send(buffer);
  }
}