const puppeteer = require("puppeteer-core");
const fs = require("fs");
const path = require("path");
const toWords = require("number-to-words");

const generateProformaPDF = async (
  invoice,
  items,
  company
) => {
  const formatDate = (date) => {
    if (!date) return "-";

    return new Date(date).toLocaleDateString(
      "en-GB"
    );
  };

  const amountInWords = (num) => {
    try {
      return (
        toWords
          .toWords(Math.round(num || 0))
          .replace(/-/g, " ") +
        " Rupees Only"
      );
    } catch {
      return "Zero Rupees Only";
    }
  };

  const formatMoney = (val) => {
    return Number(val || 0).toLocaleString(
      "en-IN",
      {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
      }
    );
  };

  try {
    // =========================
    // TEMPLATE
    // =========================

    const templatePath = path.join(
      __dirname,
      "../../templates/proformaInvoiceTemplate.html"
    );

    const logoPath = path.join(
      __dirname,
      "../../uploads/images/logo.png"
    );

    const logoBase64 = fs.readFileSync(
      logoPath,
      "base64"
    );

    const logoUrl = `data:image/png;base64,${logoBase64}`;

    let html = fs.readFileSync(
      templatePath,
      "utf8"
    );

    const bank = company.bank_details || {};

    // =========================
    // COMPANY
    // =========================

    html = html.replace(
      /{{logo_url}}/g,
      logoUrl
    );

    html = html.replace(
      /{{company_name}}/g,
      company.org_name || ""
    );

    html = html.replace(
      /{{company_address}}/g,
      company.address || ""
    );

    html = html.replace(
      /{{company_gstin}}/g,
      company.gstin || ""
    );

    html = html.replace(
      /{{company_cin}}/g,
      company.cin || ""
    );

    html = html.replace(
      /{{company_phone}}/g,
      company.phone || ""
    );

    html = html.replace(
      /{{company_email}}/g,
      company.email || ""
    );

    // =========================
    // BANK
    // =========================

    html = html.replace(
      /{{bank_name}}/g,
      bank.bank_name || ""
    );

    html = html.replace(
      /{{bank_branch}}/g,
      bank.branch || ""
    );

    html = html.replace(
      /{{account_no}}/g,
      bank.account_no || ""
    );

    html = html.replace(
      /{{ifsc}}/g,
      bank.ifsc || ""
    );

    // =========================
    // CUSTOMER
    // =========================

    html = html.replace(
      /{{customer_name}}/g,
      invoice.customer_name || ""
    );

    html = html.replace(
      /{{customer_address}}/g,
      invoice.customer_address || ""
    );

    html = html.replace(
      /{{customer_gst}}/g,
      invoice.customer_gst || ""
    );

    // =========================
    // PROFORMA DETAILS
    // =========================

    html = html.replace(
      /{{invoice_number}}/g,
      invoice.proforma_number || "-"
    );

    html = html.replace(
      /{{invoice_date}}/g,
      formatDate(
        invoice.proforma_date || new Date()
      )
    );

    html = html.replace(
      /{{order_no}}/g,
      invoice.so_number || "-"
    );

    html = html.replace(
      /{{po_no}}/g,
      invoice.po_reference || "-"
    );

    html = html.replace(
      /{{po_date}}/g,
      formatDate(invoice.delivery_date)
    );

    // =========================
    // CALCULATIONS
    // =========================

    const grossAmount = Number(
      invoice.total_amount || 0
    );

    const advancePercent = Number(
      invoice.advance_payment_percent || 0
    );

    const advanceAmount = Number(
      invoice.advance_payment_amount || 0
    );

    const balanceAmount =
      grossAmount - advanceAmount;

    // =========================
    // SUMMARY
    // =========================

    html = html.replace(
      /{{gross}}/g,
      formatMoney(grossAmount)
    );

    html = html.replace(
      /{{advance_percent}}/g,
      formatMoney(advancePercent)
    );

    html = html.replace(
      /{{advance_amount}}/g,
      formatMoney(advanceAmount)
    );

    html = html.replace(
      /{{balance_amount}}/g,
      formatMoney(balanceAmount)
    );

    html = html.replace(
      /{{total}}/g,
      formatMoney(advanceAmount)
    );

    html = html.replace(
      /{{amount_words}}/g,
      amountInWords(advanceAmount)
    );

    // =========================
    // USERS
    // =========================

    html = html.replace(
      /{{prepared_by}}/g,
      invoice.prepared_by || "-"
    );

    html = html.replace(
      /{{approved_by}}/g,
      invoice.approved_by || "-"
    );

    // =========================
    // ITEMS
    // =========================

    let itemsRows = "";

    items.forEach((item) => {
      itemsRows += `
        <tr>
          <td class="product-name">
            ${item.product_name || "-"}
          </td>

          <td class="text-center">
            ${item.hsn || "-"}
          </td>

          <td class="text-center">
            ${item.uom_symbol || "-"}
          </td>

          <td class="text-center">
            ${item.qty || 0}
          </td>

          <td class="text-right">
            ${Number(item.rate || 0).toFixed(2)}
          </td>

          <td class="text-right">
            ${Number(item.amount || 0).toFixed(2)}
          </td>
        </tr>
      `;
    });

    html = html.replace(
      "{{items_rows}}",
      itemsRows
    );

    // =========================
    // PDF GENERATION
    // =========================

    const browser = await puppeteer.launch({
      headless: true,

      executablePath:
        "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",

      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
        "--disable-gpu",
      ],
    });

    const page = await browser.newPage();

    await page.setContent(html, {
      waitUntil: "load",
    });

    const pdf = await page.pdf({
      format: "A4",
      printBackground: true,
    });

    await browser.close();

    return pdf;
  } catch (err) {
    console.error(
      "PROFORMA PDF ERROR:",
      err
    );

    throw err;
  }
};

module.exports = generateProformaPDF;