/**
 * PDF Adapter
 *
 * Implements PdfPort using pdfkit
 */

import { Injectable, Logger } from '@nestjs/common';
import PDFDocument from 'pdfkit';
import { PdfPort, BookingPdfData } from '@domain/ports/out/pdf.port';

@Injectable()
export class PdfAdapter implements PdfPort {
  private readonly logger = new Logger(PdfAdapter.name);

  async generateBookingConfirmation(data: BookingPdfData): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      try {
        const doc = new PDFDocument({
          size: 'A4',
          margin: 50,
        });

        const buffers: Buffer[] = [];
        doc.on('data', buffers.push.bind(buffers));
        doc.on('end', () => {
          const pdfBuffer = Buffer.concat(buffers);
          this.logger.log(`Generated booking confirmation PDF for ${data.bookingNumber}`);
          resolve(pdfBuffer);
        });

        // Header
        doc.fontSize(24).fillColor('#0066cc').text('BOOKING CONFIRMATION', { align: 'center' });

        doc.moveDown();

        // Booking Number
        doc
          .fontSize(16)
          .fillColor('#333333')
          .text(`Booking Number: ${data.bookingNumber}`, { align: 'center' });

        doc
          .fontSize(10)
          .fillColor('#666666')
          .text(`Date: ${data.bookingDate.toLocaleDateString()}`, {
            align: 'center',
          });

        doc.moveDown(2);

        // Route Information
        doc.fontSize(14).fillColor('#0066cc').text('Route Information');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc.fontSize(12).fillColor('#333333');
        doc.text(`Origin: ${data.origin.name} (${data.origin.code})`);
        doc.text(`Destination: ${data.destination.name} (${data.destination.code})`);
        doc.text(`Carrier: ${data.carrier.name}`);
        doc.text(`ETD: ${data.etd.toLocaleDateString()}`);
        doc.text(`ETA: ${data.eta.toLocaleDateString()}`);
        doc.text(`Transit Time: ${data.transitDays} days`);

        doc.moveDown(2);

        // Shipper Information
        doc.fontSize(14).fillColor('#0066cc').text('Shipper Information');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc.fontSize(12).fillColor('#333333');
        doc.text(`Name: ${data.shipper.name}`);
        doc.text(`Address: ${data.shipper.address}`);
        doc.text(`Contact: ${data.shipper.contact}`);
        doc.text(`Email: ${data.shipper.email}`);
        doc.text(`Phone: ${data.shipper.phone}`);

        doc.moveDown(2);

        // Consignee Information
        doc.fontSize(14).fillColor('#0066cc').text('Consignee Information');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc.fontSize(12).fillColor('#333333');
        doc.text(`Name: ${data.consignee.name}`);
        doc.text(`Address: ${data.consignee.address}`);
        doc.text(`Contact: ${data.consignee.contact}`);
        doc.text(`Email: ${data.consignee.email}`);
        doc.text(`Phone: ${data.consignee.phone}`);

        doc.moveDown(2);

        // Container Information
        doc.fontSize(14).fillColor('#0066cc').text('Container Details');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc.fontSize(12).fillColor('#333333');
        data.containers.forEach((container, index) => {
          doc.text(`${index + 1}. Type: ${container.type} | Quantity: ${container.quantity}`);
          if (container.containerNumber) {
            doc.text(`   Container #: ${container.containerNumber}`);
          }
          if (container.sealNumber) {
            doc.text(`   Seal #: ${container.sealNumber}`);
          }
        });

        doc.moveDown(2);

        // Cargo Description
        doc.fontSize(14).fillColor('#0066cc').text('Cargo Description');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc.fontSize(12).fillColor('#333333').text(data.cargoDescription);

        if (data.specialInstructions) {
          doc.moveDown();
          doc.fontSize(14).fillColor('#0066cc').text('Special Instructions');
          doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
          doc.moveDown();
          doc.fontSize(12).fillColor('#333333').text(data.specialInstructions);
        }

        doc.moveDown(2);

        // Price
        doc.fontSize(14).fillColor('#0066cc').text('Total Price');
        doc.moveTo(50, doc.y).lineTo(550, doc.y).stroke();
        doc.moveDown();

        doc
          .fontSize(16)
          .fillColor('#333333')
          .text(`${data.price.currency} ${data.price.amount.toLocaleString()}`, {
            align: 'center',
          });

        doc.moveDown(3);

        // Footer
        doc
          .fontSize(10)
          .fillColor('#666666')
          .text('This is a system-generated document. No signature required.', { align: 'center' });

        doc.text('© 2025 Xpeditis. All rights reserved.', { align: 'center' });

        doc.end();
      } catch (error) {
        this.logger.error('Failed to generate PDF', error);
        reject(error);
      }
    });
  }

  async generateRateQuoteComparison(quotes: any[]): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      try {
        const doc = new PDFDocument({
          size: 'A4',
          margin: 50,
          layout: 'landscape',
        });

        const buffers: Buffer[] = [];
        doc.on('data', buffers.push.bind(buffers));
        doc.on('end', () => {
          const pdfBuffer = Buffer.concat(buffers);
          this.logger.log('Generated rate quote comparison PDF');
          resolve(pdfBuffer);
        });

        // Header
        doc.fontSize(20).fillColor('#0066cc').text('RATE QUOTE COMPARISON', { align: 'center' });

        doc.moveDown(2);

        // Table Header
        const startY = doc.y;
        doc.fontSize(10).fillColor('#0066cc');
        doc.text('Carrier', 50, startY, { width: 100 });
        doc.text('Price', 160, startY, { width: 80 });
        doc.text('Transit Days', 250, startY, { width: 80 });
        doc.text('ETD', 340, startY, { width: 80 });
        doc.text('ETA', 430, startY, { width: 80 });
        doc.text('Route', 520, startY, { width: 200 });

        doc
          .moveTo(50, doc.y + 5)
          .lineTo(750, doc.y + 5)
          .stroke();
        doc.moveDown();

        // Table Rows
        doc.fontSize(9).fillColor('#333333');
        quotes.forEach(quote => {
          const rowY = doc.y;
          doc.text(quote.carrier.name, 50, rowY, { width: 100 });
          doc.text(`${quote.price.currency} ${quote.price.amount}`, 160, rowY, { width: 80 });
          doc.text(quote.transitDays.toString(), 250, rowY, { width: 80 });
          doc.text(new Date(quote.etd).toLocaleDateString(), 340, rowY, {
            width: 80,
          });
          doc.text(new Date(quote.eta).toLocaleDateString(), 430, rowY, {
            width: 80,
          });
          doc.text(`${quote.origin.code} → ${quote.destination.code}`, 520, rowY, {
            width: 200,
          });
          doc.moveDown();
        });

        doc.moveDown(2);

        // Footer
        doc.fontSize(10).fillColor('#666666').text('Generated by Xpeditis', { align: 'center' });

        doc.end();
      } catch (error) {
        this.logger.error('Failed to generate rate comparison PDF', error);
        reject(error);
      }
    });
  }
}
