const db = require('../models');
const { sendResponse, sendError } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const PDFDocument = require('pdfkit');

/**
 * Generate PDF for Approved Suppliers Report
 */
exports.generatePDF = asyncHandler(async (req, res) => {
  const { companyId, company_id } = req.query;
  const companyIdValue = companyId || company_id || req.user?.companyId;

  if (!companyIdValue) {
    return sendError(res, 'Company ID is required', 400);
  }

  // Get approved vendors (suppliers)
  const approvedSuppliers = await db.BusinessPartner.findAll({
    where: {
      company_id: companyIdValue,
      bp_type: { [db.Sequelize.Op.in]: ['VENDOR', 'BOTH'] },
      approval_status: 'APPROVED',
      status: 'ACTIVE'
    },
    include: [
      {
        model: db.BPAddress,
        as: 'addresses',
        where: { 
          status: 'ACTIVE',
          is_default: true
        },
        required: false,
        include: [
          { model: db.City, as: 'city', attributes: ['id', 'city_name'] },
          { model: db.State, as: 'state', attributes: ['id', 'state_name', 'state_code'] },
          { model: db.Country, as: 'country', attributes: ['id', 'country_name'] },
        ]
      },
      {
        model: db.BPGSTIN,
        as: 'gstins',
        where: { 
          status: 'ACTIVE',
          is_default: true
        },
        required: false,
        include: [
          { model: db.State, as: 'state', attributes: ['id', 'state_name', 'gst_state_code'] }
        ]
      },
      {
        model: db.VendorCategory,
        as: 'vendorCategory',
        attributes: ['id', 'category_code', 'category_name'],
        required: false
      }
    ],
    order: [['name', 'ASC']]
  });

  // Get document number from document master
  let documentNumber = null;
  let revisionNumber = '1';
  let revisionDate = new Date().toLocaleDateString('en-GB');
  const document = await db.Document.findOne({
    where: {
      company_id: companyIdValue,
      erp_module: 'BUSINESS_PARTNER',
      status: 'ACTIVE'
    },
    order: [['id', 'DESC']]
  });
  if (document) {
    documentNumber = document.document_number;
  }

  // Get company details
  const company = await db.Company.findByPk(companyIdValue, {
    attributes: ['id', 'code', 'name', 'legal_name']
  });

  if (!company) {
    return sendError(res, 'Company not found', 404);
  }

  // Create PDF
  const doc = new PDFDocument({ 
    margin: 40,
    size: 'A4',
    layout: 'landscape' // Landscape for better table width
  });
  
  const filename = `Approved_Suppliers_${documentNumber || 'Report'}.pdf`;
  
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
  
  doc.pipe(res);

  // Constants
  const pageWidth = doc.page.width;
  const pageHeight = doc.page.height;
  const margin = 40;
  const contentWidth = pageWidth - (margin * 2);
  
  // Draw document info box (top right)
  const boxWidth = 140;
  const boxHeight = 52;
  const boxX = pageWidth - margin - boxWidth;
  const boxY = margin;
  
  doc.fontSize(9)
     .font('Helvetica-Bold');
  
  // Draw box border
  doc.rect(boxX, boxY, boxWidth, boxHeight).stroke();
  
  // Box content with better spacing
  let boxContentY = boxY + 10;
  const labelX = boxX + 8;
  const valueX = boxX + 65;
  
  // Doc. No
  doc.text('Doc. No:', labelX, boxContentY, { continued: false, width: 55 });
  doc.font('Helvetica').text(documentNumber || 'RI/PUR/F/01', valueX, boxContentY, { width: 70 });
  
  boxContentY += 14;
  // Rev. No
  doc.font('Helvetica-Bold').text('Rev. No:', labelX, boxContentY, { continued: false, width: 55 });
  doc.font('Helvetica').text(revisionNumber, valueX, boxContentY, { width: 70 });
  
  boxContentY += 14;
  // Rev. Date
  doc.font('Helvetica-Bold').text('Rev. Date:', labelX, boxContentY, { continued: false, width: 55 });
  doc.font('Helvetica').text(revisionDate, valueX, boxContentY, { width: 70 });

  // Header Section
  let yPosition = margin + 12;
  doc.fontSize(17)
     .font('Helvetica-Bold')
     .text('LIST OF APPROVED SUPPLIERS', margin, yPosition, {
       align: 'center',
       width: contentWidth
     });
  
  yPosition += 28;
  doc.fontSize(13)
     .font('Helvetica')
     .text(company.name || company.legal_name, margin, yPosition, {
       align: 'center',
       width: contentWidth
     });

  yPosition += 32;

  // Table setup
  const tableTop = yPosition;
  const rowHeight = 28;
  const headerHeight = 32;
  
  // Column definitions (adjusted for landscape)
  const columns = [
    { header: 'SI No', x: margin, width: 35, align: 'center' },
    { header: 'Supplier code', x: margin + 35, width: 70, align: 'left' },
    { header: 'Supplier name', x: margin + 105, width: 120, align: 'left' },
    { header: 'Contact no', x: margin + 225, width: 75, align: 'left' },
    { header: 'Email / Website', x: margin + 300, width: 100, align: 'left' },
    { header: 'Scope of Supply', x: margin + 400, width: 80, align: 'left' },
    { header: 'GST No.', x: margin + 480, width: 90, align: 'left' },
    { header: 'PAN No.', x: margin + 570, width: 75, align: 'left' },
    { header: 'Address', x: margin + 645, width: 110, align: 'left' }
  ];

  // Helper function to draw table header
  const drawTableHeader = (y) => {
    // Header background
    doc.rect(margin, y, contentWidth, headerHeight).fillAndStroke('#d0d0d0', '#000000');
    
    // Header text
    doc.fillColor('#000000')
       .fontSize(9)
       .font('Helvetica-Bold');
    
    columns.forEach(col => {
      doc.text(col.header, col.x + 4, y + 11, {
        width: col.width - 8,
        align: col.align
      });
    });
    
    // Draw column borders
    columns.forEach(col => {
      doc.moveTo(col.x, y)
         .lineTo(col.x, y + headerHeight)
         .stroke();
    });
    
    return y + headerHeight;
  };

  // Draw initial header
  yPosition = drawTableHeader(tableTop);

  // Helper function to check if we need a new page
  const checkNewPage = (currentY, requiredHeight) => {
    if (currentY + requiredHeight > pageHeight - margin - 50) {
      doc.addPage();
      return drawTableHeader(margin);
    }
    return currentY;
  };

  // Draw table rows
  approvedSuppliers.forEach((supplier, index) => {
    // Check if we need a new page
    yPosition = checkNewPage(yPosition, rowHeight);
    
    // Format data
    const defaultAddress = supplier.addresses?.[0] || null;
    const defaultGSTIN = supplier.gstins?.[0] || null;
    
    let address = '';
    if (defaultAddress) {
      const parts = [
        defaultAddress.address_line1,
        defaultAddress.address_line2,
        defaultAddress.city?.city_name,
        defaultAddress.state?.state_name,
        defaultAddress.pincode
      ].filter(Boolean);
      address = parts.join(', ');
    }

    const rowData = [
      { value: (index + 1).toString(), align: 'center' },
      { value: supplier.bp_number || '-', align: 'left' },
      { value: supplier.name || '-', align: 'left' },
      { value: supplier.contact_no || '-', align: 'left' },
      { value: supplier.email || supplier.website || '-', align: 'left' },
      { value: supplier.vendorCategory?.category_name || '-', align: 'left' },
      { value: defaultGSTIN?.gstin || '-', align: 'left' },
      { value: supplier.pan || '-', align: 'left' },
      { value: address || '-', align: 'left' }
    ];

    // Row background (alternating colors)
    const bgColor = index % 2 === 0 ? '#ffffff' : '#e8f5e9';
    doc.rect(margin, yPosition, contentWidth, rowHeight)
       .fillAndStroke(bgColor, '#000000');

    // Row text
    doc.fillColor('#000000')
       .fontSize(8.5)
       .font('Helvetica');
    
    columns.forEach((col, colIndex) => {
      const data = rowData[colIndex];
      doc.text(data.value, col.x + 4, yPosition + 7, {
        width: col.width - 8,
        height: rowHeight - 14,
        align: data.align,
        ellipsis: true
      });
    });
    
    // Draw column borders
    columns.forEach(col => {
      doc.moveTo(col.x, yPosition)
         .lineTo(col.x, yPosition + rowHeight)
         .stroke();
    });

    yPosition += rowHeight;
  });

  // Draw bottom border of table
  doc.moveTo(margin, yPosition)
     .lineTo(pageWidth - margin, yPosition)
     .stroke();

  // Finalize PDF
  doc.end();
});
