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

exports.generatePDF = asyncHandler(async (req, res) => {
  const { id } = req.params;

  // Fetch report with all relations
  const report = await db.IncomingInspectionReport.findByPk(id, {
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.Plant,
        as: 'plant',
        attributes: ['id', 'code', 'name']
      },
      {
        model: db.BusinessPartner,
        as: 'supplier',
        attributes: ['id', 'bp_number', 'name', 'legal_name']
      },
      {
        model: db.Material,
        as: 'material',
        attributes: ['id', 'material_code', 'material_description']
      },
      {
        model: db.IncomingInspectionReportDetail,
        as: 'details',
        include: [
          {
            model: db.MeasuringInstrument,
            as: 'measuringInstrument',
            attributes: ['id', 'instrument_id', 'description']
          }
        ],
        order: [['line_no', 'ASC']]
      }
    ]
  });

  if (!report) {
    return sendError(res, 'Incoming Inspection Report not found', 404);
  }

  // Fetch Print Header for logo
  const printHeader = await db.PrintHeader.findOne({
    where: { company_id: report.company_id, status: 'ACTIVE' },
    order: [['id', 'DESC']]
  });

  let companyLogoPath = null;
  if (printHeader?.logo_path) {
    let fullPath = path.join(__dirname, '..', 'uploads', printHeader.logo_path);
    if (fs.existsSync(fullPath)) {
      companyLogoPath = fullPath;
    } else {
      fullPath = path.join(__dirname, '..', printHeader.logo_path);
      if (fs.existsSync(fullPath)) companyLogoPath = fullPath;
    }
  }

  // Create PDF
  const doc = new PDFDocument({ margin: 20, size: 'A4', layout: 'landscape', bufferPages: true });
  const filename = `IIR_${report.iir_no || report.id}.pdf`;
  
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `inline; filename="${filename}"`);
  doc.pipe(res);

  // Page dimensions (landscape A4)
  const pageWidth = 841.89;
  const pageHeight = 595.28;
  const margin = 20;
  const contentWidth = pageWidth - (margin * 2);

  const lineColor = '#000000';
  const lineWidth = 0.5;
  const headerBgColor = '#e8e8e8';

  // Helper functions
  const drawCell = (x, y, w, h, opts = {}) => {
    const { fillColor = null, borderWidth = lineWidth, strokeColor = lineColor } = opts;
    doc.save();
    doc.lineWidth(borderWidth);
    if (fillColor) {
      doc.fillColor(fillColor).rect(x, y, w, h).fill();
    }
    doc.strokeColor(strokeColor).rect(x, y, w, h).stroke();
    doc.restore();
  };

  const drawText = (text, x, y, w, h, opts = {}) => {
    const {
      align = 'left',
      valign = 'middle',
      fontSize = 9,
      bold = false,
      padding = 4,
      textColor = '#000000'
    } = opts;

    if (text === null || text === undefined) text = '';

    doc.save();
    doc.font(bold ? 'Helvetica-Bold' : 'Helvetica').fontSize(fontSize).fillColor(textColor);

    let textY = y + padding;
    if (valign === 'middle') {
      textY = y + (h - fontSize) / 2;
    } else if (valign === 'bottom') {
      textY = y + h - fontSize - padding;
    }

    doc.text(text.toString(), x + padding, textY, {
      width: w - padding * 2,
      align,
      lineBreak: false,
      ellipsis: true
    });
    doc.restore();
  };

  // Start Y position
  let currentY = margin;

  // Header Section
  const headerHeight = 80;
  drawCell(margin, currentY, contentWidth, headerHeight, { fillColor: '#ffffff' });

  // Logo
  if (companyLogoPath) {
    try {
      doc.image(companyLogoPath, margin + 10, currentY + 10, { fit: [60, 60], align: 'center', valign: 'center' });
    } catch (error) {
      console.error('Logo error:', error);
    }
  }

  // Company Name
  const companyNameX = margin + 80;
  const companyNameWidth = contentWidth - 320;
  drawText(
    printHeader?.company_name || report.company?.name || 'RAM INDUSTRIES',
    companyNameX,
    currentY + 15,
    companyNameWidth,
    20,
    { align: 'center', fontSize: 16, bold: true }
  );

  // Title
  drawText(
    'INCOMING INSPECTION REPORT',
    companyNameX,
    currentY + 40,
    companyNameWidth,
    20,
    { align: 'center', fontSize: 14, bold: true }
  );

  // Date and IIR No on right
  const rightBoxX = pageWidth - margin - 200;
  const rightBoxW = 200;
  
  drawCell(rightBoxX, currentY + 10, rightBoxW, 25);
  drawText('Date', rightBoxX, currentY + 10, 60, 25, { bold: true, align: 'center' });
  doc.moveTo(rightBoxX + 60, currentY + 10).lineTo(rightBoxX + 60, currentY + 35).stroke();
  drawText(report.iir_date || '', rightBoxX + 60, currentY + 10, rightBoxW - 60, 25, { align: 'center' });

  drawCell(rightBoxX, currentY + 35, rightBoxW, 25);
  drawText('IIR No.', rightBoxX, currentY + 35, 60, 25, { bold: true, align: 'center' });
  doc.moveTo(rightBoxX + 60, currentY + 35).lineTo(rightBoxX + 60, currentY + 60).stroke();
  drawText(report.iir_no || '', rightBoxX + 60, currentY + 35, rightBoxW - 60, 25, { align: 'center' });

  currentY += headerHeight + 5;

  // Part and Supplier Information
  const infoRowH = 25;
  
  // Row 1: Part Name and Part No
  drawCell(margin, currentY, 150, infoRowH, { fillColor: headerBgColor });
  drawText('Part Name', margin, currentY, 150, infoRowH, { bold: true });
  
  drawCell(margin + 150, currentY, contentWidth - 450, infoRowH);
  drawText(report.part_name || '', margin + 150, currentY, contentWidth - 450, infoRowH);
  
  drawCell(pageWidth - margin - 300, currentY, 100, infoRowH, { fillColor: headerBgColor });
  drawText('Part No.', pageWidth - margin - 300, currentY, 100, infoRowH, { bold: true });
  
  drawCell(pageWidth - margin - 200, currentY, 200, infoRowH);
  drawText(report.part_no || '', pageWidth - margin - 200, currentY, 200, infoRowH);
  
  currentY += infoRowH;

  // Row 2: Supplier and DC No/Date
  drawCell(margin, currentY, 150, infoRowH, { fillColor: headerBgColor });
  drawText('Supplier', margin, currentY, 150, infoRowH, { bold: true });
  
  drawCell(margin + 150, currentY, contentWidth - 450, infoRowH);
  drawText(report.supplier_name || report.supplier?.name || '', margin + 150, currentY, contentWidth - 450, infoRowH);
  
  drawCell(pageWidth - margin - 300, currentY, 100, infoRowH, { fillColor: headerBgColor });
  drawText('DC No. / Date', pageWidth - margin - 300, currentY, 100, infoRowH, { bold: true });
  
  drawCell(pageWidth - margin - 200, currentY, 100, infoRowH);
  drawText(report.dc_no || '', pageWidth - margin - 200, currentY, 100, infoRowH);
  
  drawCell(pageWidth - margin - 100, currentY, 100, infoRowH);
  drawText(report.dc_date || '', pageWidth - margin - 100, currentY, 100, infoRowH);
  
  currentY += infoRowH + 5;

  // Inspection Table
  const tableStartY = currentY;
  const slW = 30;
  const parameterW = 120;
  const specificationW = 100;
  const instrumentW = 80;
  const obsW = 45;
  const rowH = 25;

  // Table Header
  drawCell(margin, currentY, slW, rowH * 2, { fillColor: headerBgColor });
  drawText('Sl\nNo', margin, currentY, slW, rowH * 2, { bold: true, align: 'center', valign: 'middle' });

  drawCell(margin + slW, currentY, parameterW, rowH * 2, { fillColor: headerBgColor });
  drawText('PARAMETER', margin + slW, currentY, parameterW, rowH * 2, { bold: true, align: 'center', valign: 'middle' });

  drawCell(margin + slW + parameterW, currentY, specificationW, rowH * 2, { fillColor: headerBgColor });
  drawText('SPECIFICATION', margin + slW + parameterW, currentY, specificationW, rowH * 2, { bold: true, align: 'center', valign: 'middle' });

  drawCell(margin + slW + parameterW + specificationW, currentY, instrumentW, rowH * 2, { fillColor: headerBgColor });
  drawText('INSTRU\nMENT', margin + slW + parameterW + specificationW, currentY, instrumentW, rowH * 2, { bold: true, align: 'center', valign: 'middle' });

  const obsStartX = margin + slW + parameterW + specificationW + instrumentW;
  drawCell(obsStartX, currentY, obsW * 8, rowH, { fillColor: headerBgColor });
  drawText('OBSERVED VALUES (MAX / MIN )', obsStartX, currentY, obsW * 8, rowH, { bold: true, align: 'center' });

  currentY += rowH;

  // Observation column numbers
  for (let i = 0; i < 8; i++) {
    drawCell(obsStartX + (i * obsW), currentY, obsW, rowH, { fillColor: headerBgColor });
    drawText((i + 1).toString(), obsStartX + (i * obsW), currentY, obsW, rowH, { bold: true, align: 'center' });
  }

  currentY += rowH;

  // Table Data
  const details = report.details || [];
  details.forEach((detail, index) => {
    if (currentY + rowH > pageHeight - margin - 60) {
      // Add new page if needed
      doc.addPage({ margin, size: 'A4', layout: 'landscape' });
      currentY = margin;
    }

    drawCell(margin, currentY, slW, rowH);
    drawText((index + 1).toString(), margin, currentY, slW, rowH, { align: 'center' });

    drawCell(margin + slW, currentY, parameterW, rowH);
    drawText(detail.parameter || '', margin + slW, currentY, parameterW, rowH, { fontSize: 8 });

    drawCell(margin + slW + parameterW, currentY, specificationW, rowH);
    drawText(detail.specification || '', margin + slW + parameterW, currentY, specificationW, rowH, { fontSize: 8 });

    drawCell(margin + slW + parameterW + specificationW, currentY, instrumentW, rowH);
    const instrumentText = detail.measuringInstrument?.instrument_id || detail.instrument || '';
    drawText(instrumentText, margin + slW + parameterW + specificationW, currentY, instrumentW, rowH, { fontSize: 8 });

    for (let i = 1; i <= 8; i++) {
      drawCell(obsStartX + ((i - 1) * obsW), currentY, obsW, rowH);
      drawText(detail[`observation_${i}`] || '', obsStartX + ((i - 1) * obsW), currentY, obsW, rowH, { align: 'center', fontSize: 8 });
    }

    currentY += rowH;
  });

  // Add empty rows to reach at least 6 rows
  const minRows = 6;
  for (let i = details.length; i < minRows; i++) {
    drawCell(margin, currentY, slW, rowH);
    drawCell(margin + slW, currentY, parameterW, rowH);
    drawCell(margin + slW + parameterW, currentY, specificationW, rowH);
    drawCell(margin + slW + parameterW + specificationW, currentY, instrumentW, rowH);
    for (let j = 0; j < 8; j++) {
      drawCell(obsStartX + (j * obsW), currentY, obsW, rowH);
    }
    currentY += rowH;
  }

  currentY += 5;

  // Footer Section
  const footerRowH = 30;
  const remarksW = contentWidth - 300;
  const accRejW = 150;

  // Remarks, Acc, Rej row
  drawCell(margin, currentY, 100, footerRowH, { fillColor: headerBgColor });
  drawText('Remarks', margin, currentY, 100, footerRowH, { bold: true, valign: 'top' });

  drawCell(margin + 100, currentY, remarksW - 100, footerRowH);
  drawText(report.remarks || '', margin + 100, currentY, remarksW - 100, footerRowH, { fontSize: 8, valign: 'top' });

  drawCell(margin + remarksW, currentY, 75, footerRowH, { fillColor: headerBgColor });
  drawText('Acc.', margin + remarksW, currentY, 75, footerRowH, { bold: true, align: 'center' });

  drawCell(margin + remarksW + 75, currentY, 75, footerRowH);
  drawText(report.accepted_qty ? parseFloat(report.accepted_qty).toFixed(2) : '', margin + remarksW + 75, currentY, 75, footerRowH, { align: 'center' });

  drawCell(margin + remarksW + 150, currentY, 75, footerRowH, { fillColor: headerBgColor });
  drawText('Rej.', margin + remarksW + 150, currentY, 75, footerRowH, { bold: true, align: 'center' });

  drawCell(margin + remarksW + 225, currentY, 75, footerRowH);
  drawText(report.rejected_qty ? parseFloat(report.rejected_qty).toFixed(2) : '', margin + remarksW + 225, currentY, 75, footerRowH, { align: 'center' });

  currentY += footerRowH;

  // Inspected By and Approved By row
  const signatureRowH = 40;
  const halfWidth = contentWidth / 2;

  drawCell(margin, currentY, halfWidth / 3, signatureRowH, { fillColor: headerBgColor });
  drawText('Inspected By', margin, currentY, halfWidth / 3, signatureRowH, { bold: true, valign: 'top' });

  drawCell(margin + halfWidth / 3, currentY, halfWidth - halfWidth / 3, signatureRowH);
  drawText(report.inspected_by || '', margin + halfWidth / 3, currentY, halfWidth - halfWidth / 3, signatureRowH, { valign: 'top' });

  drawCell(margin + halfWidth, currentY, halfWidth / 3, signatureRowH, { fillColor: headerBgColor });
  drawText('Approved By', margin + halfWidth, currentY, halfWidth / 3, signatureRowH, { bold: true, valign: 'top' });

  drawCell(margin + halfWidth + halfWidth / 3, currentY, halfWidth - halfWidth / 3, signatureRowH);
  drawText(report.approved_by || '', margin + halfWidth + halfWidth / 3, currentY, halfWidth - halfWidth / 3, signatureRowH, { valign: 'top' });

  // Document reference at bottom right
  currentY += signatureRowH + 10;
  drawText('RI/QA/F/01', pageWidth - margin - 100, pageHeight - margin - 15, 100, 15, { align: 'right', fontSize: 8 });

  doc.end();
});
