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

/**
 * Generate PDF for a single Machine History Card row (matches the printed form layout).
 * Route: GET /api/v1/production/machine-history-card/:id/pdf
 */
exports.generatePDF = asyncHandler(async (req, res) => {
  const { id } = req.params;

  const historyCard = await db.MachineHistoryCard.findByPk(id, {
    include: [
      { model: db.Company, as: 'company', attributes: ['id', 'code', 'name'] },
      { model: db.Plant, as: 'plant', attributes: ['id', 'code', 'name'] },
      { model: db.FiscalYear, as: 'fiscalYear', attributes: ['id', 'fiscal_year'] },
      { model: db.Machine, as: 'machine', attributes: ['id', 'machine_code', 'machine_description', 'history_card_no'] },
      { model: db.User, as: 'creator', attributes: ['id', 'username', 'email'] }
    ]
  });

  if (!historyCard) {
    return sendError(res, 'Machine History Card not found', 404);
  }

  // Optional: fetch print header and document number if configured
  const printHeader = await db.PrintHeader.findOne({
    where: { company_id: historyCard.company_id, status: 'ACTIVE' },
    order: [['id', 'DESC']]
  });

  const document =
    (await db.Document.findOne({
      where: { company_id: historyCard.company_id, erp_module: 'MACHINE_HISTORY_CARD', status: 'ACTIVE' },
      order: [['id', 'DESC']]
    })) ||
    (await db.Document.findOne({
      where: { company_id: historyCard.company_id, erp_module: 'MACHINE_HISTORY', status: 'ACTIVE' },
      order: [['id', 'DESC']]
    }));

  const companyName = printHeader?.company_name || historyCard.company?.name || 'RAM INDUSTRIES';
  const docNumber = document?.document_number || 'RI/MN/F/02';
  const docRevision = 'Rev.0/01.10.18';

  const formatDate = (dateString) => {
    if (!dateString) return '';
    const d = new Date(dateString);
    const day = String(d.getDate()).padStart(2, '0');
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const year = d.getFullYear();
    return `${day}.${month}.${year}`;
  };

  const formatTime = (timeValue) => {
    if (!timeValue) return '';
    const s = String(timeValue);
    return s.length >= 5 ? s.slice(0, 5) : s;
  };

  const formatCost = (value) => {
    if (value === null || value === undefined || value === '') return '';
    const n = Number(value);
    if (Number.isNaN(n)) return String(value);
    return n.toFixed(2);
  };

  // Create PDF in landscape orientation
  const doc = new PDFDocument({ margin: 30, size: 'A4', layout: 'landscape', bufferPages: true });
  const safeMachineNo =
    historyCard.machine?.history_card_no ||
    historyCard.machine_number ||
    historyCard.machine?.machine_code ||
    historyCard.machine_id ||
    historyCard.id;
  const filename = `Machine_History_Card_${safeMachineNo}_${Date.now()}.pdf`;

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
  doc.pipe(res);

  const pageWidth = 841.89; // A4 landscape
  const pageHeight = 595.28;
  const margin = 30;
  const contentWidth = pageWidth - margin * 2;

  const borderColor = '#000000';
  const lineWidth = 1;

  let y = margin;

  // ==================== HEADER ====================
  const headerRow1H = 45; // Increased from 36 for better printability
  const headerRow2H = 35; // Increased from 28 for better printability

  const leftW = 150;
  const rightW = 160;
  const centerW = contentWidth - leftW - rightW;

  const x0 = margin;

  // Row 1: Draw outer rectangle
  doc.rect(x0, y, contentWidth, headerRow1H).lineWidth(lineWidth).stroke(borderColor);
  
  // Draw vertical separators
  doc.moveTo(x0 + leftW, y).lineTo(x0 + leftW, y + headerRow1H).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(x0 + leftW + centerW, y).lineTo(x0 + leftW + centerW, y + headerRow1H).lineWidth(lineWidth).stroke(borderColor);

  // Text for row 1 - vertically centered with increased height
  doc.fontSize(13).font('Helvetica-Bold').fillColor('#000000');
  doc.text(companyName.toUpperCase(), x0 + 5, y + 15, { width: leftW - 10, align: 'center' });
  
  doc.fontSize(15).font('Helvetica-Bold');
  doc.text('MACHINE HISTORY CARD', x0 + leftW + 5, y + 13, { width: centerW - 10, align: 'center' });

  doc.fontSize(12).font('Helvetica-Bold');
  doc.text(docNumber, x0 + leftW + centerW + 5, y + 10, { width: rightW - 10, align: 'right' });
  doc.fontSize(10).font('Helvetica');
  doc.text(docRevision, x0 + leftW + centerW + 5, y + 27, { width: rightW - 10, align: 'right' });

  y += headerRow1H;

  // Row 2: Machine No | Machine Description
  const halfW = contentWidth / 2;
  doc.rect(x0, y, contentWidth, headerRow2H).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(x0 + halfW, y).lineTo(x0 + halfW, y + headerRow2H).lineWidth(lineWidth).stroke(borderColor);

  const machineNo =
    historyCard.machine?.history_card_no ||
    historyCard.machine_number ||
    historyCard.machine?.machine_code ||
    '';
  const machineDesc =
    historyCard.machine?.machine_description ||
    historyCard.machine_description ||
    '';

  doc.fontSize(11).font('Helvetica').fillColor('#000000');
  const row2TextY = y + 12; // Adjusted for increased height
  doc.text('Machine No:', x0 + 8, row2TextY, { width: 80, continued: true });
  doc.font('Helvetica-Bold');
  doc.text(`  ${machineNo}`, { width: halfW - 100 });

  doc.font('Helvetica');
  doc.text('Machine Description:', x0 + halfW + 8, row2TextY, { width: 130, continued: true });
  doc.font('Helvetica-Bold');
  doc.text(`  ${machineDesc}`, { width: halfW - 150 });

  y += headerRow2H;

  // ==================== TABLE ====================
  const col = {
    date: 70,
    details: 150,
    idleFrom: 55,
    idleTo: 55,
    idleTotal: 60,
    action: 160,
    spares: 90,
    cost: 70,
    sign: 75
  };

  const headerTopH = 28; // Increased from 24 for better printability
  const headerSubH = 26; // Increased from 22 for better printability
  const rowH = 40;

  // Calculate positions
  let xPos = x0;
  const xDate = xPos;
  const xDetails = xDate + col.date;
  const xIdle = xDetails + col.details;
  const xIdleFrom = xIdle;
  const xIdleTo = xIdleFrom + col.idleFrom;
  const xIdleTotal = xIdleTo + col.idleTo;
  const xAction = xIdle + col.idleFrom + col.idleTo + col.idleTotal;
  const xSpares = xAction + col.action;
  const xCost = xSpares + col.spares;
  const xSign = xCost + col.cost;

  const topY = y;
  const totalHeaderH = headerTopH + headerSubH;

  // Draw outer table rectangle
  doc.rect(x0, topY, contentWidth, totalHeaderH).lineWidth(lineWidth).stroke(borderColor);

  // Draw top header row separator
  doc.moveTo(x0, topY + headerTopH).lineTo(x0 + contentWidth, topY + headerTopH).lineWidth(lineWidth).stroke(borderColor);

  // Draw vertical lines for columns
  doc.moveTo(xDetails, topY).lineTo(xDetails, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xIdle, topY).lineTo(xIdle, topY + headerTopH).lineWidth(lineWidth).stroke(borderColor); // Idle Time top only
  doc.moveTo(xIdleFrom, topY + headerTopH).lineTo(xIdleFrom, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xIdleTo, topY + headerTopH).lineTo(xIdleTo, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xIdleTotal, topY + headerTopH).lineTo(xIdleTotal, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xAction, topY).lineTo(xAction, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xSpares, topY).lineTo(xSpares, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xCost, topY).lineTo(xCost, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);
  doc.moveTo(xSign, topY).lineTo(xSign, topY + totalHeaderH).lineWidth(lineWidth).stroke(borderColor);

  // Header text - top row (vertically centered with increased height)
  doc.fontSize(11).font('Helvetica-Bold').fillColor('#000000');
  doc.text('Date', xDate, topY + 10, { width: col.date, align: 'center' });
  doc.text('Details of the Problem', xDetails + 5, topY + 10, { width: col.details - 10, align: 'center' });
  doc.text('Idle Time', xIdle, topY + 7, { width: col.idleFrom + col.idleTo + col.idleTotal, align: 'center' });
  doc.text('Action Taken', xAction + 5, topY + 10, { width: col.action - 10, align: 'center' });
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('Spares Replaced\nif any', xSpares + 5, topY + 5, { width: col.spares - 10, align: 'center' });
  doc.text('Cost (if\nknown)', xCost + 5, topY + 7, { width: col.cost - 10, align: 'center' });
  doc.fontSize(11).font('Helvetica-Bold');
  doc.text('Sign', xSign, topY + 10, { width: col.sign, align: 'center' });

  // Header text - sub row (vertically centered with increased height)
  doc.fontSize(10).font('Helvetica-Bold');
  const subY = topY + headerTopH;
  doc.text('From', xIdleFrom, subY + 7, { width: col.idleFrom, align: 'center' });
  doc.text('To', xIdleTo, subY + 7, { width: col.idleTo, align: 'center' });
  doc.text('Total Hrs', xIdleTotal, subY + 7, { width: col.idleTotal, align: 'center' });

  y += totalHeaderH;

  // Body rows
  const rowValues = {
    date: formatDate(historyCard.date),
    details: historyCard.problem_details || '',
    idleFrom: formatTime(historyCard.idle_time_from),
    idleTo: formatTime(historyCard.idle_time_to),
    idleTotal: historyCard.total_idle_hours != null ? String(historyCard.total_idle_hours) : '',
    action: historyCard.action_taken || '',
    spares: historyCard.spares_replaced || '',
    cost: formatCost(historyCard.cost_if_known),
    sign: historyCard.signed_by || ''
  };

  const rowsToRender = 10;

  for (let i = 0; i < rowsToRender; i++) {
    const rowY = y + i * rowH;
    if (rowY + rowH > pageHeight - margin - 10) break;

    const v = i === 0 ? rowValues : {};

    // Draw row rectangle
    doc.rect(x0, rowY, contentWidth, rowH).lineWidth(lineWidth).stroke(borderColor);

    // Draw vertical lines
    doc.moveTo(xDetails, rowY).lineTo(xDetails, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xIdleFrom, rowY).lineTo(xIdleFrom, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xIdleTo, rowY).lineTo(xIdleTo, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xIdleTotal, rowY).lineTo(xIdleTotal, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xAction, rowY).lineTo(xAction, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xSpares, rowY).lineTo(xSpares, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xCost, rowY).lineTo(xCost, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);
    doc.moveTo(xSign, rowY).lineTo(xSign, rowY + rowH).lineWidth(lineWidth).stroke(borderColor);

    // Add text content
    if (v.date || v.details || v.idleFrom) {
      doc.fontSize(9).font('Helvetica').fillColor('#000000');
      const textY = rowY + (rowH - 10) / 2;

      if (v.date) doc.text(v.date, xDate, textY, { width: col.date, align: 'center' });
      if (v.details) doc.text(v.details, xDetails + 4, rowY + 6, { width: col.details - 8, align: 'left' });
      if (v.idleFrom) doc.text(v.idleFrom, xIdleFrom, textY, { width: col.idleFrom, align: 'center' });
      if (v.idleTo) doc.text(v.idleTo, xIdleTo, textY, { width: col.idleTo, align: 'center' });
      if (v.idleTotal) {
        doc.font('Helvetica-Bold');
        doc.text(v.idleTotal, xIdleTotal, textY, { width: col.idleTotal, align: 'center' });
        doc.font('Helvetica');
      }
      if (v.action) doc.text(v.action, xAction + 4, rowY + 6, { width: col.action - 8, align: 'left' });
      if (v.spares) doc.text(v.spares, xSpares + 4, textY, { width: col.spares - 8, align: 'center' });
      if (v.cost) doc.text(v.cost, xCost, textY, { width: col.cost, align: 'center' });
      if (v.sign) doc.text(v.sign, xSign, textY, { width: col.sign, align: 'center' });
    }
  }

  doc.end();
});
