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;

  const report = await db.AssemblyFinalInspectionReport.findByPk(id, {
    include: [
      { model: db.Company, as: 'company', attributes: ['id', 'code', 'name'] },
      { model: db.BusinessPartner, as: 'customer', attributes: ['id', 'bp_number', 'name', 'legal_name'] },
      { model: db.User, as: 'chargeSignBy', attributes: ['id', 'first_name', 'last_name'] },
      { model: db.User, as: 'inspectedByUser', attributes: ['id', 'first_name', 'last_name'] },
      { model: db.AssemblyFinalInspectionReportDetail, as: 'details', order: [['line_no', 'ASC']] }
    ]
  });

  if (!report) return sendError(res, 'Assembly Final Inspection Report not found', 404);

  const workOrder = report.work_order_no
    ? await db.WorkOrder.findOne({
      where: {
        work_order_number: report.work_order_no,
        company_id: report.company_id
      },
      include: [
        {
          model: db.Material,
          as: 'finishedMaterial',
          attributes: ['material_number', 'description'],
          required: false
        }
      ]
    })
    : null;
  const productCode = workOrder?.finishedMaterial?.material_number || report.model || '';
  const productName = workOrder?.finishedMaterial?.description || report.model || '';

  const printHeader = await db.PrintHeader.findOne({
    where: { company_id: report.company_id, status: 'ACTIVE' },
    order: [['id', 'DESC']]
  });
  let companyLogoPath = null;
  if (printHeader?.logo_path) {
    const fullPath = path.join(__dirname, '..', 'uploads', printHeader.logo_path);
    if (fs.existsSync(fullPath)) companyLogoPath = fullPath;
  }

  const doc = new PDFDocument({ margin: 30, size: 'A4', bufferPages: true });
  const filename = `AFIR_${report.report_no || report.id}.pdf`;
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
  doc.pipe(res);

  const margin = 20;
  const pageWidth = doc.page.width;
  const contentWidth = pageWidth - margin * 2;

  doc.lineWidth(0.8).strokeColor('#000000');

  const drawBox = (x, y, w, h) => {
    doc.rect(x, y, w, h).stroke();
  };
  const drawCellText = (text, x, y, w, h, opts = {}) => {
    const { align = 'left', bold = false, size = 7, padX = 2, padY = 2, lineBreak = false } = opts;
    doc.font(bold ? 'Helvetica-Bold' : 'Helvetica').fontSize(size).fillColor('#000');
    doc.text(String(text || ''), x + padX, y + padY, {
      width: w - padX * 2,
      height: h - padY * 2,
      align,
      lineBreak,
      ellipsis: !lineBreak
    });
  };
  const fmtDateDMY = (value) => {
    if (!value) return '';
    const d = new Date(value);
    if (Number.isNaN(d.getTime())) return String(value);
    const dd = String(d.getDate()).padStart(2, '0');
    const mm = String(d.getMonth() + 1).padStart(2, '0');
    const yyyy = d.getFullYear();
    return `${dd}/${mm}/${yyyy}`;
  };
  const fmtCellValue = (val) => {
    if (val === null || val === undefined || val === '') return '';
    return String(val);
  };
  const isTickValue = (val) => ['1', 'y', 'yes', 'true', 'tick', 'ticked', 'check', 'checked', '✓', '✔']
    .includes(String(val || '').trim().toLowerCase());
  const drawTick = (x, y, w, h) => {
    const sx = x + w * 0.34;
    const sy = y + h * 0.58;
    const mx = x + w * 0.45;
    const my = y + h * 0.72;
    const ex = x + w * 0.7;
    const ey = y + h * 0.35;
    doc.save();
    doc.lineWidth(1).strokeColor('#000');
    doc.moveTo(sx, sy).lineTo(mx, my).lineTo(ex, ey).stroke();
    doc.restore();
  };
  const hLine = (x1, x2, yy) => {
    doc.moveTo(x1, yy).lineTo(x2, yy).stroke();
  };
  const vLine = (xx, y1, y2) => {
    doc.moveTo(xx, y1).lineTo(xx, y2).stroke();
  };

  let y = margin;

  // Title row (Dimensional-like format)
  const titleH = 18;
  drawBox(margin, y, contentWidth, titleH);
  drawCellText('ASSEMBLY - FINAL INSPECTION REPORT', margin, y, contentWidth, titleH, { align: 'center', bold: true, size: 9, padY: 4 });
  drawCellText(report.doc_no || 'RI/QA/F/05', margin + contentWidth - 94, y, 92, titleH, { align: 'right', size: 8, padY: 4 });
  y += titleH;

  // Header info block (close to dimensional style)
  const headerH = 64;
  const logoW = 62;
  const leftW = 214;
  const midW = 132;
  const rightW = contentWidth - logoW - leftW - midW;
  const logoX = margin;
  const leftX = logoX + logoW;
  const midX = leftX + leftW;
  const rightX = midX + midW;

  drawBox(margin, y, contentWidth, headerH);
  vLine(leftX, y, y + headerH);
  vLine(midX, y, y + headerH);
  vLine(rightX, y, y + headerH);
  hLine(leftX, midX, y + 21);
  hLine(leftX, midX, y + 42);
  hLine(midX, rightX, y + 21);
  hLine(midX, rightX, y + 42);
  hLine(rightX, margin + contentWidth, y + 32);

  if (companyLogoPath) {
    try {
      doc.image(companyLogoPath, logoX + 4, y + 4, { fit: [logoW - 8, headerH - 8], align: 'center', valign: 'center' });
    } catch (_) {
      drawCellText(report.company?.name || 'RAM INDUSTRIES', logoX, y, logoW, headerH, { align: 'center', bold: true, size: 7, lineBreak: true, padY: 18 });
    }
  } else {
    drawCellText(report.company?.name || 'RAM INDUSTRIES', logoX, y, logoW, headerH, { align: 'center', bold: true, size: 7, lineBreak: true, padY: 18 });
  }

  drawCellText('WORK ORDER NO', leftX + 2, y, 86, 21, { bold: true, size: 7.5, padY: 6 });
  drawCellText(report.work_order_no || '', leftX + 88, y, leftW - 90, 21, { bold: true, size: 8.5, padY: 5 });
  drawCellText('PRODUCT NAME', leftX + 2, y + 21, 86, 21, { bold: true, size: 7.5, padY: 6 });
  drawCellText(productName, leftX + 88, y + 21, leftW - 90, 21, { bold: true, size: 8, padY: 4, lineBreak: true });
  drawCellText('PRODUCT CODE', leftX + 2, y + 42, 86, 22, { bold: true, size: 7.5, padY: 6 });
  drawCellText(productCode, leftX + 88, y + 42, leftW - 90, 22, { bold: true, size: 8.5, padY: 5 });

  drawCellText('Date', midX + 3, y, 42, 21, { bold: true, size: 7.5, padY: 6 });
  drawCellText(fmtDateDMY(report.report_date), midX + 45, y, midW - 48, 21, { size: 8, padY: 5 });
  drawCellText('REV.No', midX + 3, y + 21, 42, 21, { bold: true, size: 7.5, padY: 6 });
  drawCellText(report.rev_no || '', midX + 45, y + 21, midW - 48, 21, { size: 7.5, padY: 4, lineBreak: true });
  drawCellText('WQ.QTY', midX + 3, y + 42, 42, 22, { bold: true, size: 7.5, padY: 6 });
  drawCellText(String(report.total_qty ?? ''), midX + 45, y + 42, midW - 48, 22, { size: 7.5, padY: 4, lineBreak: true });

  drawCellText('Customer Name', rightX + 3, y, 66, 32, { bold: true, size: 7, padY: 4 });
  drawCellText(report.customer_name || report.customer?.name || '', rightX + 69, y, rightW - 72, 32, { size: 7, padY: 3, lineBreak: true });
  drawCellText('Total Qty / Sample Qty', rightX + 3, y + 32, 66, 32, { bold: true, size: 7, padY: 4 });
  drawCellText(`${report.total_qty ?? ''} / ${report.sample_qty ?? ''}`, rightX + 69, y + 32, rightW - 72, 32, { size: 7.5, padY: 4 });

  y += headerH;

  // Inspection detail table with merged Frame header (format-only)
  const colSl = 32;
  const colDesc = 126;
  const colSpec = 92;
  const colQty = 46;
  const colFrame = (contentWidth - colSl - colDesc - colSpec - colQty) / 10;
  const head1H = 16;
  const head2H = 14;
  const rowH = 24;
  const tableW = contentWidth;

  drawBox(margin, y, tableW, head1H + head2H);
  let x = margin;
  vLine(x + colSl, y, y + head1H + head2H);
  vLine(x + colSl + colDesc, y, y + head1H + head2H);
  vLine(x + colSl + colDesc + colSpec, y, y + head1H + head2H);
  vLine(x + colSl + colDesc + colSpec + colQty, y, y + head1H + head2H);
  hLine(x + colSl + colDesc + colSpec + colQty, x + tableW, y + head1H);
  for (let f = 1; f <= 9; f++) {
    vLine(x + colSl + colDesc + colSpec + colQty + colFrame * f, y + head1H, y + head1H + head2H);
  }

  drawCellText('S No.', x, y, colSl, head1H + head2H, { align: 'center', bold: true, size: 8, padY: 9 });
  x += colSl;
  drawCellText('Item Description', x, y, colDesc, head1H + head2H, { align: 'center', bold: true, size: 8, padY: 9 });
  x += colDesc;
  drawCellText('Specification', x, y, colSpec, head1H + head2H, { align: 'center', bold: true, size: 8, padY: 9 });
  x += colSpec;
  drawCellText('Qty/Set', x, y, colQty, head1H + head2H, { align: 'center', bold: true, size: 8, padY: 9 });
  x += colQty;
  drawCellText('Frame', x, y, colFrame * 10, head1H, { align: 'center', bold: true, size: 8, padY: 4 });
  for (let f = 1; f <= 10; f++) {
    drawCellText(String(f), x + colFrame * (f - 1), y + head1H, colFrame, head2H, { align: 'center', bold: true, size: 8, padY: 3 });
  }
  y += head1H + head2H;

  const details = Array.isArray(report.details) ? report.details : [];
  const rowsToRender = Math.max(details.length, 10);
  for (let i = 0; i < rowsToRender; i++) {
    const row = details[i] || {};
    drawBox(margin, y, tableW, rowH);
    let rx = margin;
    const verticals = [colSl, colDesc, colSpec, colQty];
    verticals.forEach((w) => {
      rx += w;
      vLine(rx, y, y + rowH);
    });
    for (let f = 1; f <= 9; f++) {
      vLine(rx + colFrame * f, y, y + rowH);
    }

    let tx = margin;
    drawCellText(row.line_no ?? i + 1, tx, y, colSl, rowH, { align: 'center', size: 8, padY: 8 });
    tx += colSl;
    drawCellText(row.item_description || '', tx, y, colDesc, rowH, { align: 'center', size: 7, padY: 8 });
    tx += colDesc;
    drawCellText(row.specification || '', tx, y, colSpec, rowH, { align: 'center', size: 6.7, padY: 6, lineBreak: true });
    tx += colSpec;
    drawCellText(fmtCellValue(row.qty_per_set), tx, y, colQty, rowH, { align: 'center', size: 8, padY: 8 });
    tx += colQty;
    for (let f = 1; f <= 10; f++) {
      const frameValue = row[`frame_${f}`] ?? '';
      const cellX = tx + colFrame * (f - 1);
      if (isTickValue(frameValue)) {
        drawTick(cellX, y, colFrame, rowH);
      } else {
        drawCellText(frameValue, cellX, y, colFrame, rowH, { align: 'center', size: 7, padY: 8 });
      }
    }
    y += rowH;
  }

  // Remarks block
  const remarksH = 40;
  drawBox(margin, y, contentWidth, remarksH);
  hLine(margin, margin + contentWidth, y + 14);
  drawCellText('REMARKS:', margin, y, contentWidth, 14, { bold: true, size: 9, padY: 3 });
  drawCellText(report.remarks || '', margin, y + 14, contentWidth, remarksH - 14, { size: 8, padY: 4, lineBreak: true });
  y += remarksH;

  // Signature block
  const signH = 20;
  drawBox(margin, y, contentWidth, signH);
  vLine(margin + contentWidth * 0.58, y, y + signH);
  const chargeName = report.chargeSignBy ? `${report.chargeSignBy.first_name || ''} ${report.chargeSignBy.last_name || ''}`.trim() : '';
  const inspName = report.inspectedByUser ? `${report.inspectedByUser.first_name || ''} ${report.inspectedByUser.last_name || ''}`.trim() : '';
  drawCellText(`Incharge Sign: ${chargeName}`, margin, y, contentWidth * 0.58, signH, { size: 8, padY: 6 });
  drawCellText(`Inspected By: ${inspName}`, margin + contentWidth * 0.58, y, contentWidth * 0.42, signH, { size: 8, padY: 6 });

  doc.end();
});
