import {
  Body,
  Controller,
  Delete,
  Get,
  Header,
  Param,
  Patch,
  Post,
  UseGuards,
} from '@nestjs/common';

import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { Roles } from '../../common/decorators/roles.decorator';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { RolesGuard } from '../../common/guards/roles.guard';
import type { AuthUser } from '../../common/types/auth-user.type';

import { CreatePrintLayoutDto } from './dto/create-print-layout.dto';
import { GenerateDocumentDto } from './dto/generate-document.dto';
import { UpdatePrintLayoutDto } from './dto/update-print-layout.dto';

import { DocumentType } from './entities/document.entity';
import { PrintType } from './entities/print-layout.entity';

import { DocumentsService } from './documents.service';

@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('super_admin', 'agency_manager', 'agent')
@Controller('documents')
export class DocumentsController {
  constructor(private readonly documentsService: DocumentsService) {}

  @Get()
  findAllDocuments(@CurrentUser() user: AuthUser) {
    return this.documentsService.findAllDocuments(user);
  }

  @Get(':id')
  findDocument(
    @Param('id') id: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.findDocument(Number(id), user);
  }

  @Delete(':id')
  @Roles('super_admin', 'agency_manager')
  removeDocument(
    @Param('id') id: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.removeDocument(Number(id), user);
  }

  @Post('generate')
  generateDocument(
    @Body() data: GenerateDocumentDto,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.generateDocument(data, user);
  }

  @Post('contracts/:bookingId/pdf')
  generateContractPdf(
    @Param('bookingId') bookingId: string,
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.generateDocument(
      {
        type: DocumentType.CONTRACT,
        bookingId: Number(bookingId),
        layoutId: body?.layoutId,
        printType: body?.printType || PrintType.A4_BLANK,
        language: body?.language || 'fr',
        title: body?.title || 'Contrat de location',
        metadata: body?.metadata,
      },
      user,
    );
  }

  @Post('invoices/:bookingId/pdf')
  generateInvoicePdf(
    @Param('bookingId') bookingId: string,
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.generateDocument(
      {
        type: DocumentType.INVOICE,
        bookingId: Number(bookingId),
        layoutId: body?.layoutId,
        printType: body?.printType || PrintType.A4_BLANK,
        language: body?.language || 'fr',
        title: body?.title || 'Facture',
        metadata: body?.metadata,
      },
      user,
    );
  }

  @Post('payment-receipts/:paymentId/pdf')
  generatePaymentReceiptPdf(
    @Param('paymentId') paymentId: string,
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.generateDocument(
      {
        type: DocumentType.PAYMENT_RECEIPT,
        paymentId: Number(paymentId),
        layoutId: body?.layoutId,
        printType: body?.printType || PrintType.A4_BLANK,
        language: body?.language || 'fr',
        title: body?.title || 'Reçu de paiement',
        metadata: body?.metadata,
      },
      user,
    );
  }

  @Post('vehicle-check/:bookingId/pdf')
  generateVehicleCheckPdf(
    @Param('bookingId') bookingId: string,
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.generateDocument(
      {
        type:
          body?.checkType === 'return'
            ? DocumentType.VEHICLE_CHECKIN
            : DocumentType.VEHICLE_CHECKOUT,
        bookingId: Number(bookingId),
        layoutId: body?.layoutId,
        printType: body?.printType || PrintType.A4_BLANK,
        language: body?.language || 'fr',
        title:
          body?.checkType === 'return'
            ? 'État véhicule retour'
            : 'État véhicule départ',
        metadata: body?.metadata,
      },
      user,
    );
  }

  @Patch(':id/printed')
  markPrinted(
    @Param('id') id: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.markPrinted(Number(id), user);
  }

  @Patch(':id/sign')
  signDocument(
    @Param('id') id: string,
    @Body('signatureUrl') signatureUrl: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.signDocument(
      Number(id),
      user,
      signatureUrl,
    );
  }

  @Post('print-layouts')
  @Roles('super_admin', 'agency_manager')
  createPrintLayout(
    @Body() data: CreatePrintLayoutDto,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.createPrintLayout(data, user);
  }

  @Get('print-layouts/list')
  findAllPrintLayouts(@CurrentUser() user: AuthUser) {
    return this.documentsService.findAllPrintLayouts(user);
  }

  @Get('print-layouts/:id')
  findPrintLayout(
    @Param('id') id: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.findPrintLayout(Number(id), user);
  }

  @Patch('print-layouts/:id')
  @Roles('super_admin', 'agency_manager')
  updatePrintLayout(
    @Param('id') id: string,
    @Body() data: UpdatePrintLayoutDto,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.updatePrintLayout(
      Number(id),
      data,
      user,
    );
  }

  @Delete('print-layouts/:id')
  @Roles('super_admin', 'agency_manager')
  removePrintLayout(
    @Param('id') id: string,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.removePrintLayout(Number(id), user);
  }

  @Post('print-layouts/detect-from-image')
  @Roles('super_admin', 'agency_manager')
  detectLayoutFromImage(
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.detectLayoutFromImage(user, body);
  }

  @Post('ocr/client-documents')
  @Roles('super_admin', 'agency_manager', 'agent')
  processOcr(
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.processOcr(user, body);
  }

  @Post('ai/contract-review')
  @Roles('super_admin', 'agency_manager')
  aiContractReview(
    @Body() body: any,
    @CurrentUser() user: AuthUser,
  ) {
    return this.documentsService.aiContractReview(user, body);
  }
}

/*
|--------------------------------------------------------------------------
| PUBLIC PREMIUM VERIFY CONTROLLER
|--------------------------------------------------------------------------
*/

@Controller('verify')
export class PublicDocumentsController {
  constructor(private readonly documentsService: DocumentsService) {}

  @Get('document/:token')
  @Header('Content-Type', 'text/html; charset=utf-8')
  verifyDocumentPage(@Param('token') token: string) {
    return this.documentsService.renderPublicVerifyHtml(token);
  }

  @Get('document/:token/json')
  verifyDocumentJson(@Param('token') token: string) {
    return this.documentsService.verifyPublicDocument(token);
  }
}