import { ICollection } from "@shared/contexts";
import { Quote, QuoteItem } from "../../../../../../domain";
import { ISalesContext } from "../../../../../Sales.context";

import { readFileSync } from "fs";
import * as handlebars from "handlebars";
import path from "path";
import puppeteer from "puppeteer";
import report from "puppeteer-report";

export interface IReportQuoteReporter {
  toHTML: (quote: Quote, context: ISalesContext) => Promise<string>;
  toPDF: (quote: Quote, context: ISalesContext) => Promise<Buffer>;
}

// https://plnkr.co/edit/lWk6Yd?preview

export const ReportQuotePresenter: IReportQuoteReporter = {
  toHTML: async (quote: Quote, context: ISalesContext): Promise<string> => {
    const quote_dto = await map(quote, context);

    // Obtener y compilar la plantilla HTML
    const templateHtml = readFileSync(
      path.join(__dirname, "./templates/quote/template.hbs")
    ).toString();
    const template = handlebars.compile(templateHtml, {});
    return template(quote_dto);
  },

  toPDF: async (quote: Quote, context: ISalesContext): Promise<Buffer> => {
    const html = await ReportQuotePresenter.toHTML(quote, context);

    // Generar el PDF con Puppeteer
    const browser = await puppeteer.launch({
      args: [
        "--disable-extensions",
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
        "--disable-gpu",
      ],
    });

    const page = await browser.newPage();
    const navigationPromise = page.waitForNavigation();
    await page.setContent(html, { waitUntil: "networkidle2" });

    await navigationPromise;
    const reportPDF = await report.pdfPage(page, {
      format: "a4",
      margin: {
        bottom: "10mm",
        left: "10mm",
        right: "10mm",
        top: "10mm",
      },
    });

    await browser.close();
    return Buffer.from(reportPDF);
  },
};

const map = async (quote: Quote, context: ISalesContext) => {
  const { dealer } = context;

  return {
    id: quote.id.toString(),
    status: quote.status.toString(),
    date: quote.date.toLocaleDateString(),
    reference: quote.reference.toString(),
    customer_reference: quote.customerReference.toString(),
    customer_information: quote.customer.toString(),
    lang_code: quote.language.toString(),
    currency_code: quote.currency.toString(),

    payment_method: quote.paymentMethod.toString(),
    validity: quote.validity.toString(),
    notes: quote.notes.toString(),

    subtotal_price: quote.subtotalPrice.toFormat(),

    discount: quote.discount.toFormat(),
    discount_price: quote.discountPrice.toFormat(),

    before_tax_price: quote.beforeTaxPrice.toFormat(),

    tax: quote.tax.toFormat(),
    tax_price: quote.taxPrice.toFormat(),

    total_price: quote.totalPrice.toFormat(),

    items: quoteItemPresenter(quote.items, context),

    dealer: {
      id: dealer?.id.toString(),
      name: dealer?.name.toString(),
      currency_code: dealer?.currency.code,
      lang_code: dealer?.language.code,
      contact_information: dealer?.additionalInfo.get("contact_information"),
      default_payment_method: dealer?.additionalInfo.get("default_payment_method"),
      default_notes: dealer?.additionalInfo.get("default_notes"),
      default_legal_terms: dealer?.additionalInfo.get("default_legal_terms"),
      default_quote_validity: dealer?.additionalInfo.get("default_quote_validity"),
      logo: await dealer?.logo.toBase64(),
    },
  };
};

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const quoteItemPresenter = (items: ICollection<QuoteItem>, context: ISalesContext): any[] =>
  items.totalCount > 0
    ? items.items.map((item: QuoteItem) => ({
        id_article: item.idArticle.toString(),
        description: item.description.toString(),
        quantity: item.quantity.toFormat(),
        unit_price: item.unitPrice.toFormat(),
        subtotal_price: item.subtotalPrice.toFormat(),
        discount: item.discount.toFormat(),
        total_price: item.totalPrice.toFormat(),
      }))
    : [];
2;
