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

/**
 * Generate PDF for Supplier Registration Form (Job Worker)
 * Matches the exact table-like format shown in the frontend
 */
exports.generatePDF = asyncHandler(async (req, res) => {
  const { id } = req.params;

  const businessPartner = await db.BusinessPartner.findByPk(id, {
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name', 'legal_name']
      },
      {
        model: db.VendorCategory,
        as: 'vendorCategory',
        attributes: ['id', 'category_code', 'category_name'],
        required: false
      },
      {
        model: db.BPAddress,
        as: 'addresses',
        where: { status: 'ACTIVE' },
        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.BPBank,
        as: 'banks',
        where: { status: 'ACTIVE' },
        required: false,
        include: [
          { model: db.Bank, as: 'bank', attributes: ['id', 'bank_name', 'bank_code'] }
        ]
      },
      {
        model: db.BPGSTIN,
        as: 'gstins',
        where: { status: 'ACTIVE' },
        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'] },
        ]
      }
    ]
  });

  if (!businessPartner) {
    return sendError(res, 'Business Partner not found', 404);
  }

  // Get print header
  const printHeader = await db.PrintHeader.findOne({
    where: {
      company_id: businessPartner.company_id,
      status: 'ACTIVE'
    },
    order: [['id', 'DESC']]
  });

  // Get document number
  let documentNumber = null;
  const document = await db.Document.findOne({
    where: {
      company_id: businessPartner.company_id,
      erp_module: 'BUSINESS_PARTNER',
      status: 'ACTIVE'
    },
    order: [['id', 'DESC']]
  });
  if (document) {
    documentNumber = document.document_number;
  }

  // Get addresses
  const defaultAddress = businessPartner.addresses?.find(addr => addr.is_default) || businessPartner.addresses?.[0] || null;
  const factoryAddress = businessPartner.addresses?.find(addr => addr.address_type === 'FACTORY' || addr.address_type === 'SHIPPING') || null;
  const defaultGSTIN = businessPartner.gstins?.find(gstin => gstin.is_default) || businessPartner.gstins?.[0] || null;

  // Create PDF
  const doc = new PDFDocument({ 
    margin: 35,
    size: 'A4'
  });
  
  const filename = `Supplier_Registration_${businessPartner.bp_number || businessPartner.id}.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 = 35;
  const contentWidth = pageWidth - (margin * 2);
  const labelWidth = 190; // 35% of content width
  
  // Helper function to format address
  const formatAddress = (address) => {
    if (!address) return '';
    const parts = [
      address.address_line1,
      address.address_line2,
      address.city?.city_name,
      address.state?.state_name,
      address.pincode
    ].filter(Boolean);
    return parts.join(', ');
  };

  // Helper to draw underlined field with label and value
  const drawField = (label, value, x, y, fieldWidth = null, splitLabel = false) => {
    const actualFieldWidth = fieldWidth || (contentWidth - labelWidth);
    
    doc.fontSize(9).font('Helvetica-Bold');
    doc.text(label, x, y, { width: labelWidth, continued: false });
    
    const valueX = x + labelWidth;
    const valueY = y;
    
    // Draw underline
    doc.moveTo(valueX, valueY + 12).lineTo(valueX + actualFieldWidth, valueY + 12).stroke();
    
    // Draw value
    doc.fontSize(9).font('Helvetica');
    doc.text(value || '', valueX + 2, valueY, { width: actualFieldWidth - 4 });
    
    return y + 20;
  };

  // Helper to draw radio buttons
  const drawRadioButton = (x, y, selected = false, label = '') => {
    // Draw circle
    doc.circle(x + 5, y + 5, 4).stroke();
    if (selected) {
      doc.circle(x + 5, y + 5, 2.5).fill('black');
    }
    
    // Draw label
    if (label) {
      doc.fontSize(8).font('Helvetica');
      doc.text(label, x + 12, y + 1, { width: 80 });
    }
    
    return x + (label ? 70 : 15);
  };

  let yPosition = margin;

  // ==================== HEADER ====================
  // Company Name (Left)
  doc.fontSize(13).font('Helvetica-Bold');
  doc.text(printHeader?.company_name || businessPartner.company?.name || 'Ram Industries', margin, yPosition);
  
  // Title (Center)
  doc.fontSize(12).font('Helvetica-Bold');
  const titleText = 'SUPPLIER REGISTRATION FORM';
  const titleWidth = doc.widthOfString(titleText);
  doc.text(titleText, (pageWidth - titleWidth) / 2, yPosition);
  
  // Document Number (Right)
  if (documentNumber) {
    doc.fontSize(10).font('Helvetica-Bold');
    const docNumText = documentNumber;
    const docNumWidth = doc.widthOfString(docNumText);
    doc.text(docNumText, pageWidth - margin - docNumWidth, yPosition);
  }

  yPosition += 18;
  
  // Horizontal line
  doc.moveTo(margin, yPosition).lineTo(pageWidth - margin, yPosition).lineWidth(1.5).stroke();
  yPosition += 12;

  // ==================== SECTION 1: GENERAL COMPANY INFORMATION ====================
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('1. General Company Information', margin, yPosition);
  doc.moveTo(margin, yPosition + 12).lineTo(margin + 170, yPosition + 12).stroke();
  yPosition += 18;

  // 1. Name of the Supplier
  yPosition = drawField('1  Name of the Supplier:', businessPartner.name || '', margin, yPosition);

  // 2. Year of establishment
  yPosition = drawField('2  Year of establishment:', businessPartner.year_of_establishment || '', margin, yPosition);

  // 3. Area (in Sq. ft.)
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('3  Area (in Sq. ft.):', margin, yPosition);
  yPosition += 14;
  
  // Total Area and Built-up area
  doc.fontSize(8).font('Helvetica');
  const areaX = margin + 20;
  doc.text('Total Area:', areaX, yPosition);
  doc.moveTo(areaX + 55, yPosition + 10).lineTo(areaX + 135, yPosition + 10).stroke();
  doc.text(businessPartner.total_area_sqft ? `${businessPartner.total_area_sqft} sq. ft.` : '', areaX + 57, yPosition);
  
  doc.text('Built-up area:', areaX + 150, yPosition);
  doc.moveTo(areaX + 210, yPosition + 10).lineTo(areaX + 295, yPosition + 10).stroke();
  doc.text(businessPartner.built_up_area_sqft ? `${businessPartner.built_up_area_sqft} sq. ft.` : '', areaX + 212, yPosition);
  yPosition += 18;
  
  // Building type radio buttons
  let radioX = areaX;
  radioX = drawRadioButton(radioX, yPosition, businessPartner.building_type === 'OWN', 'Own Building');
  radioX = drawRadioButton(radioX, yPosition, businessPartner.building_type === 'RENTED', 'Rented Building');
  yPosition += 18;

  // 4. Address
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('4  Address:', margin, yPosition);
  yPosition += 14;
  
  doc.fontSize(8).font('Helvetica');
  doc.text('Office Address:', margin + 20, yPosition);
  doc.moveTo(margin + 85, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(formatAddress(defaultAddress), margin + 87, yPosition, { width: pageWidth - margin - 90 });
  yPosition += 18;
  
  doc.text('Factory Address:', margin + 20, yPosition);
  doc.moveTo(margin + 90, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(formatAddress(factoryAddress || defaultAddress), margin + 92, yPosition, { width: pageWidth - margin - 95 });
  yPosition += 18;

  // 5. Nature of Business
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('5  Nature of Business *:', margin, yPosition);
  yPosition += 14;
  
  radioX = margin + 20;
  const natureTypes = [
    { value: 'MANUFACTURER', label: 'Manufacturer' },
    { value: 'DEALER', label: 'Dealer' },
    { value: 'AGENCY', label: 'Agency' },
    { value: 'JOB_ORDER', label: 'Job-Order' }
  ];
  natureTypes.forEach(type => {
    radioX = drawRadioButton(radioX, yPosition, businessPartner.nature_of_business === type.value, type.label);
  });
  yPosition += 18;

  // 6. Nature of Manufacturing / Service
  yPosition = drawField('6  Nature of Manufacturing / Service:', businessPartner.nature_of_manufacturing_service || '', margin, yPosition);

  // 7. Type of Company
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('7  Type of Company *:', margin, yPosition);
  yPosition += 14;
  
  radioX = margin + 20;
  const companyTypes = [
    { value: 'PUBLIC', label: 'Public' },
    { value: 'PRIVATE_LTD', label: 'Private Ltd' },
    { value: 'PARTNERSHIP', label: 'Partnership' },
    { value: 'PROPRIETORY', label: 'Proprietory' }
  ];
  companyTypes.forEach(type => {
    radioX = drawRadioButton(radioX, yPosition, businessPartner.company_type === type.value, type.label);
  });
  yPosition += 18;

  // 8. Registration no.
  yPosition = drawField('8  Registration no.:', businessPartner.registration_number || '', margin, yPosition);

  // 9. GST No. and PAN No.
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('9  GST No.:', margin, yPosition);
  yPosition += 14;
  
  doc.fontSize(8).font('Helvetica');
  const gstX = margin + 20;
  doc.text('GST IN:', gstX, yPosition);
  doc.moveTo(gstX + 45, yPosition + 10).lineTo(gstX + 190, yPosition + 10).stroke();
  doc.text(defaultGSTIN?.gstin || '', gstX + 47, yPosition);
  
  doc.text('PAN No.:', gstX + 210, yPosition);
  doc.moveTo(gstX + 255, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(businessPartner.pan || '', gstX + 257, yPosition);
  yPosition += 22;

  // ==================== SECTION 2: COMMUNICATION AND MANAGEMENT DETAILS ====================
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('2. Communication and Management Details', margin, yPosition);
  doc.moveTo(margin, yPosition + 12).lineTo(margin + 245, yPosition + 12).stroke();
  yPosition += 18;

  // 10. Communication
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('10  Communication:', margin, yPosition);
  yPosition += 14;
  
  doc.fontSize(8).font('Helvetica');
  const commX = margin + 20;
  
  doc.text('Phone Number (s):', commX, yPosition);
  doc.moveTo(commX + 90, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(businessPartner.phone_numbers || defaultAddress?.phone || '', commX + 92, yPosition);
  yPosition += 16;
  
  doc.text('Mobile no.:', commX, yPosition);
  doc.moveTo(commX + 90, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(defaultAddress?.mobile || '', commX + 92, yPosition);
  yPosition += 16;
  
  doc.text('Fax no.:', commX, yPosition);
  doc.moveTo(commX + 90, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(businessPartner.fax_number || '', commX + 92, yPosition);
  yPosition += 16;
  
  doc.text('E-mail:', commX, yPosition);
  doc.moveTo(commX + 90, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
  doc.text(defaultAddress?.email || businessPartner.email || '', commX + 92, yPosition);
  yPosition += 18;

  // 11. MD / Partner / Proprietor Name
  yPosition = drawField('11  MD / Partner / Proprietor Name (s):', businessPartner.md_partner_proprietor_name || '', margin, yPosition);
  
  // Experience
  yPosition = drawField('     and Experience in the field:', businessPartner.experience_in_field || '', margin, yPosition);

  // Check if we need a new page
  if (yPosition > pageHeight - 200) {
    doc.addPage();
    yPosition = margin;
  }

  // ==================== SECTION 3: OPERATIONAL CAPACITY AND EQUIPMENT ====================
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('3. Operational Capacity and Equipment', margin, yPosition);
  doc.moveTo(margin, yPosition + 12).lineTo(margin + 230, yPosition + 12).stroke();
  yPosition += 18;

  // 12. Available handling facilities
  yPosition = drawField('12  Available handling facilities (Transport etc.):', businessPartner.handling_facilities || '', margin, yPosition);

  // 13. Capacity
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('13  Capacity:', margin, yPosition);
  yPosition += 14;
  
  doc.fontSize(8).font('Helvetica');
  const capX = margin + 20;
  doc.text('Plant:', capX, yPosition);
  doc.moveTo(capX + 35, yPosition + 10).lineTo(capX + 100, yPosition + 10).stroke();
  doc.text(businessPartner.capacity_plant || '', capX + 37, yPosition);
  
  doc.text('Installed:', capX + 115, yPosition);
  doc.moveTo(capX + 155, yPosition + 10).lineTo(capX + 220, yPosition + 10).stroke();
  doc.text(businessPartner.capacity_installed || '', capX + 157, yPosition);
  
  doc.text('Spare:', capX + 235, yPosition);
  doc.moveTo(capX + 265, yPosition + 10).lineTo(capX + 330, yPosition + 10).stroke();
  doc.text(businessPartner.capacity_spare || '', capX + 267, yPosition);
  yPosition += 18;
  
  // Generator availability
  doc.text('Is it Generator available?', capX, yPosition);
  radioX = capX + 120;
  radioX = drawRadioButton(radioX, yPosition, businessPartner.generator_available, 'YES');
  radioX = drawRadioButton(radioX, yPosition, !businessPartner.generator_available, 'NO');
  
  if (businessPartner.generator_available && businessPartner.generator_capacity) {
    doc.text('If Yes, Capacity:', radioX + 10, yPosition);
    doc.moveTo(radioX + 80, yPosition + 10).lineTo(pageWidth - margin, yPosition + 10).stroke();
    doc.text(businessPartner.generator_capacity, radioX + 82, yPosition);
  }
  yPosition += 18;

  // 14. Details of Machinery / Measuring Equipments
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('14  Details of Machinery / Measuring Equipments:', margin, yPosition);
  yPosition += 14;
  
  const boxWidth = (contentWidth - 10) / 2;
  const machineryX = margin + 20;
  const measuringX = machineryX + boxWidth + 10;
  
  doc.fontSize(8).font('Helvetica-Bold');
  doc.text('Machinery', machineryX, yPosition);
  doc.text('Measuring Equipments', measuringX, yPosition);
  yPosition += 12;
  
  // Draw boxes
  doc.rect(machineryX, yPosition, boxWidth, 60).stroke();
  doc.rect(measuringX, yPosition, boxWidth, 60).stroke();
  
  // Fill content
  doc.fontSize(8).font('Helvetica');
  doc.text(businessPartner.machinery_details || '', machineryX + 3, yPosition + 3, { width: boxWidth - 6, height: 54 });
  doc.text(businessPartner.measuring_equipments_details || '', measuringX + 3, yPosition + 3, { width: boxWidth - 6, height: 54 });
  yPosition += 65;

  // Check if we need a new page
  if (yPosition > pageHeight - 200) {
    doc.addPage();
    yPosition = margin;
  }

  // ==================== SECTION 4: HUMAN RESOURCES AND CERTIFICATIONS ====================
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('4. Human Resources and Certifications', margin, yPosition);
  doc.moveTo(margin, yPosition + 12).lineTo(margin + 230, yPosition + 12).stroke();
  yPosition += 18;

  // 15. Number of Employees
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('15  Number of Employees:', margin, yPosition);
  yPosition += 14;
  
  doc.fontSize(8).font('Helvetica');
  const empX = margin + 20;
  doc.text('Technical Staff:', empX, yPosition);
  doc.moveTo(empX + 80, yPosition + 10).lineTo(empX + 120, yPosition + 10).stroke();
  doc.text(businessPartner.employees_technical_staff || '', empX + 82, yPosition);
  
  doc.text('Skilled Workers:', empX + 135, yPosition);
  doc.moveTo(empX + 205, yPosition + 10).lineTo(empX + 245, yPosition + 10).stroke();
  doc.text(businessPartner.employees_skilled_workers || '', empX + 207, yPosition);
  yPosition += 16;
  
  doc.text('Non-Technical Staff:', empX, yPosition);
  doc.moveTo(empX + 95, yPosition + 10).lineTo(empX + 135, yPosition + 10).stroke();
  doc.text(businessPartner.employees_non_technical_staff || '', empX + 97, yPosition);
  
  doc.text('Unskilled Workers:', empX + 150, yPosition);
  doc.moveTo(empX + 230, yPosition + 10).lineTo(empX + 270, yPosition + 10).stroke();
  doc.text(businessPartner.employees_unskilled_workers || '', empX + 232, yPosition);
  yPosition += 18;

  // 16. Working hours
  yPosition = drawField('16  Working hours:', businessPartner.working_hours || '', margin, yPosition);
  
  // No. of Shifts
  yPosition = drawField('     No. of Shifts:', businessPartner.number_of_shifts || '', margin, yPosition);
  
  // Shift timings
  yPosition = drawField('     Shift timings:', businessPartner.shift_timings || '', margin, yPosition);

  // 18. ISO 9001 Certification
  doc.fontSize(9).font('Helvetica-Bold');
  doc.text('18  Is the Company Certified for ISO 9001?', margin, yPosition);
  yPosition += 14;
  
  radioX = margin + 20;
  radioX = drawRadioButton(radioX, yPosition, businessPartner.iso_9001_certified, 'YES');
  radioX = drawRadioButton(radioX, yPosition, !businessPartner.iso_9001_certified, 'NO');
  yPosition += 16;
  
  // 19. If No, certification plan
  if (!businessPartner.iso_9001_certified) {
    doc.fontSize(8).font('Helvetica');
    doc.text('19  If No, Is there any plan to get Certification?', margin + 20, yPosition);
    radioX = margin + 220;
    radioX = drawRadioButton(radioX, yPosition, businessPartner.iso_9001_certification_planned, 'YES');
    radioX = drawRadioButton(radioX, yPosition, !businessPartner.iso_9001_certification_planned, 'NO');
    yPosition += 16;
    
    if (businessPartner.iso_9001_certification_planned && businessPartner.iso_9001_certification_target) {
      doc.text('If Yes, Target:', margin + 30, yPosition);
      doc.moveTo(margin + 85, yPosition + 10).lineTo(margin + 180, yPosition + 10).stroke();
      doc.text(new Date(businessPartner.iso_9001_certification_target).toLocaleDateString(), margin + 87, yPosition);
      yPosition += 16;
    }
  }
  yPosition += 5;

  // ==================== SECTION 5: MAJOR CUSTOMER ====================
  doc.fontSize(10).font('Helvetica-Bold');
  doc.text('5. Major Customer', margin, yPosition);
  doc.moveTo(margin, yPosition + 12).lineTo(margin + 100, yPosition + 12).stroke();
  yPosition += 18;

  // 20. Major Customer
  yPosition = drawField('20  Major Customer:', businessPartner.major_customer || '', margin, yPosition);

  yPosition += 5;

  // ==================== NOTES ====================
  doc.fontSize(7).font('Helvetica').fillColor('#444');
  doc.text('Note: a) If space is not enough, please attach separate sheets. Based on the above data "Supplier assessment" will be carried out at your premises according to our quality management system requirements.', 
    margin, yPosition, { width: contentWidth, align: 'justify' });
  yPosition += 15;
  
  doc.text('      b) Dealers / Agency are requested to put "NA" for not applicable points', margin, yPosition, { width: contentWidth });
  yPosition += 10;
  
  doc.text('      * - Strikeout whichever is not applicable', margin, yPosition, { width: contentWidth });
  yPosition += 20;
  
  doc.fillColor('black');

  // Check if we need a new page for signature
  if (yPosition > pageHeight - 120) {
    doc.addPage();
    yPosition = margin;
  }

  // ==================== SIGNATURE SECTION ====================
  doc.moveTo(margin, yPosition).lineTo(pageWidth - margin, yPosition).stroke();
  yPosition += 12;

  const sigLeftX = margin;
  const sigRightX = pageWidth / 2 + 10;

  // Left side - Supplier signature
  doc.fontSize(8).font('Helvetica');
  doc.text('Date:', sigLeftX, yPosition);
  doc.moveTo(sigLeftX + 30, yPosition + 10).lineTo(sigLeftX + 120, yPosition + 10).stroke();
  doc.text(new Date().toLocaleDateString(), sigLeftX + 32, yPosition);
  
  doc.text('Supplier Signature with Stamp:', sigLeftX, yPosition + 20);
  doc.rect(sigLeftX, yPosition + 35, 200, 40).stroke();

  // Right side - For company use
  doc.fontSize(8).font('Helvetica-Bold');
  doc.text(`(For ${printHeader?.company_name || 'Company'} Use)`, sigRightX, yPosition);
  
  doc.fontSize(8).font('Helvetica');
  doc.text('Approved By:', sigRightX, yPosition + 20);
  doc.moveTo(sigRightX + 65, yPosition + 30).lineTo(sigRightX + 190, yPosition + 30).stroke();
  
  doc.text('Supplier Code:', sigRightX, yPosition + 38);
  doc.moveTo(sigRightX + 75, yPosition + 48).lineTo(sigRightX + 190, yPosition + 48).stroke();
  doc.text(businessPartner.bp_number || '', sigRightX + 77, yPosition + 38);
  
  doc.text('Approval Status:', sigRightX, yPosition + 56);
  doc.moveTo(sigRightX + 80, yPosition + 66).lineTo(sigRightX + 190, yPosition + 66).stroke();

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