import { useParseFloat } from "@/utils/lib/helpers";
import { Button, Modal } from "flowbite-react";
import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";
import { useSession } from "next-auth/react";
import { FC, useRef, useState } from "react";
import { MdPrint } from "react-icons/md";
import { TSinvoiceSchema } from "../forms/schema/invoice";
import Spinner from "../spinner";

interface props {
  invoices: TSinvoiceSchema[];
  isShow?: boolean;
  setShow?: (x: boolean) => void;
}

interface singleInvoiceProps {
  invoice: TSinvoiceSchema;
}

export const dateFormat = () => {
  const date = new Date();
  const day = date.getDate();
  const month = date.toLocaleString("en-US", { month: "long" });
  const year = date.getFullYear().toString().slice(-2);
  const formattedDate = `${day}-${month}-${year}`;
  return formattedDate;
};

const BulkInvoicePrint: FC<props> = ({
  invoices,
  isShow = false,
  setShow = () => { },
}) => {
  const [loading, setLoading] = useState(false);
  const pdfRef = useRef<HTMLDivElement>(null);

  const handleGeneratePDF = async () => {
    setLoading(true);
    const inputData = pdfRef.current;
    if (!inputData || invoices.length === 0) {
      setLoading(false);
      return;
    }

    try {
      const canvas = await html2canvas(inputData, {
        scale: 2,
        useCORS: true,
      });
      const imgData = canvas.toDataURL("image/png");
      const document_height = inputData.clientHeight ?? 400;
      const mm_height = (document_height) / 3;

      // Use first invoice's client name for the file name
      const firstInvoice = invoices[0];
      const client_name =
        firstInvoice?.client?.name?.replace(/\s+/g, "-").toLowerCase() ?? "bulk";
      const pdf_name = `bulk-invoices-${client_name}-${dateFormat()}`;

      const pdf = new jsPDF({
        orientation: "p",
        unit: "mm",
        format: [95, mm_height],
        compress: true,
      });
      pdf.setProperties({
        title: pdf_name,
      });

      const height = pdf.internal.pageSize.getHeight();
      pdf.addImage(imgData, "PNG", 14, 0, 75, height);
      pdf.save(`${pdf_name}.pdf`);
      setLoading(false);
      setShow(false);
    } catch (error) {
      console.log(error);
      setLoading(false);
    }
  };

  // Calculate totals across all invoices
  const grandTotal = invoices.reduce((sum, inv) => sum + (inv.after_discount_amount || 0), 0);
  const totalPaid = invoices.reduce((sum, inv) => sum + (inv.amount_paid || 0), 0);
  const totalDiscount = invoices.reduce((sum, inv) => sum + (inv.total_discount || 0), 0);
  const totalDue = invoices.reduce((sum, inv) => sum + (inv.amount_due || 0), 0);
  const totalSubTotal = invoices.reduce((sum, inv) => sum + (inv.total_amount || 0), 0);

  return (
    <>
      <Modal onClose={() => setShow(false)} show={isShow} size={"sm"}>
        <Modal.Header className="border-b dark:border-gray-500 border-gray-900-0 px-2 pb-0 pt-2">
          <Button
            size={"sm"}
            color={"white"}
            className=""
            onClick={() => handleGeneratePDF()}
          >
            {loading ? <Spinner /> : <MdPrint className="text-2xl" />}
          </Button>
        </Modal.Header>
        <Modal.Body className="px-2 pb-6 pt-0 relative max-h-[70vh] overflow-y-auto">
          <div ref={pdfRef} className="dark:text-gray-200">
            <div className="flex justify-center dark:text-gray-200">
              <div className={`py-4 px-4 invoice font-bold w-full`}>
                {/* Single Header - Company and Client Info */}
                <InvoiceHeader invoice={invoices[0]} />

                {/* All Invoice Items */}
                {invoices.map((invoice, index) => (
                  <div key={invoice.trackID || invoice.id || index}>
                    <InvoiceItems invoice={invoice} />
                    {index < invoices.length - 1 && (
                      <div className="border-t-2 border-dashed border-gray-400 dark:border-gray-600 my-4" />
                    )}
                  </div>
                ))}

                {/* Single Summary at the End */}
                <InvoiceSummary
                  grandTotal={grandTotal}
                  totalPaid={totalPaid}
                  totalDiscount={totalDiscount}
                  totalDue={totalDue}
                  totalSubTotal={totalSubTotal}
                />
              </div>
            </div>
          </div>
        </Modal.Body>
      </Modal>
    </>
  );
};

// Header component - Company and Client info (shown once)
const InvoiceHeader: FC<singleInvoiceProps> = ({ invoice }) => {
  const { data: session }: any = useSession();
  return (
    <div className="flex flex-col items-center text-center text-md font-bold">
      <div>
        <div className="company mb-1 pb-1">
          <h2 className="text-lg text-gray-900 dark:text-gray-200">
            {invoice?.client?.name}
          </h2>
          <h4 className="text-gray-900 text-md font-medium dark:text-gray-200">
            {session?.company?.address}
          </h4>
          <p className="text-gray-900 text-md font-medium dark:text-gray-200">
            Phone: {invoice?.client?.phone}
          </p>
        </div>
        {invoice?.client && (
          <div className="client border-t dark:border-gray-500 border-gray-900 mt-1 pt-1 text-gray-900 dark:text-gray-200 text-md font-medium">
            <h1>Client: {invoice?.client?.name}</h1>
            {invoice?.client?.phone && (
              <p>Phone: {invoice?.client?.phone}</p>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

// Invoice Items component - Individual invoice details (trackID, date, lines, subtotal, discount)
const InvoiceItems: FC<singleInvoiceProps> = ({ invoice }) => {
  return (
    <>
      <div className="flex justify-between text-md font-bold mt-3 pb-2 mb-1 text-md font-medium">
        <div>
          <p> #{invoice?.trackID}</p>
        </div>
        <div>
          <p>{dateFormat()}</p>
        </div>
      </div>
      <div className="grid gap-2 grid-cols-5 font-medium pb-1 text-md border-t dark:border-gray-500 border-gray-900">
        <div className="col-span-2 py-1">Item</div>
        <div className="py-1 text-center">Qty</div>
        <div className="py-1">Price</div>
        <div className="flex justify-end py-1">Amt</div>
      </div>
      <div className="border-t dark:border-gray-500 border-gray-900 mt-1 font-medium text-md">
        {invoice?.lines?.map((line: any) => (
          <div
            key={line.uuid}
            className="grid gap-2 grid-cols-5 border-b dark:border-gray-500 border-gray-900 pb-2"
          >
            <div className="col-span-2 py-1">{line?.description}</div>
            <div className="py-1 text-center">{line.quantity}</div>
            <div className="py-1 text-left -ml-1">
              {useParseFloat(line?.amount)}
            </div>
            <div className="flex justify-end py-1">
              {useParseFloat(line?.total_amount)}
            </div>
          </div>
        ))}
      </div>
      <div className="mt-1 text-md font-medium pb-2">
        <div className="flex justify-end mb-1">
          <div className="mr-4">Sub Total:</div>
          <div className="w-[60px]  text-right">
            {useParseFloat(invoice?.total_amount)}
          </div>
        </div>
        <div className="flex justify-end">
          <div className="mr-4"> Discount:</div>
          <div className="w-[60px]  text-right">
            {useParseFloat(invoice?.total_discount)}
          </div>
        </div>
        <div className="flex justify-end border-t dark:border-gray-500 border-gray-900 pt-2">
          <div className="mr-4"> Amount Paid:</div>
          <div className="w-[60px]  text-right">
            {useParseFloat(invoice?.amount_paid)}
          </div>
        </div>
      </div>
    </>
  );
};

// Summary component - Final totals across all invoices
interface SummaryProps {
  grandTotal: number;
  totalPaid: number;
  totalDiscount: number;
  totalDue: number;
  totalSubTotal: number;
}

const InvoiceSummary: FC<SummaryProps> = ({
  grandTotal,
  totalPaid,
  totalDiscount,
  totalDue,
  totalSubTotal,
}) => {
  return (
    <div className="mt-3 text-md font-medium pb-2 border-t dark:border-gray-500 border-gray-900 pt-3">
      <div className="flex justify-end mb-1">
        <div className="mr-4">Sub Total:</div>
        <div className="w-[60px]  text-right">
          {useParseFloat(totalSubTotal)}
        </div>
      </div>
      <div className="flex justify-end mb-1 pb-2">
        <div className="mr-4">Discount:</div>
        <div className="w-[60px]  text-right">
          {useParseFloat(totalDiscount)}
        </div>
      </div>
      {grandTotal > totalPaid ? (
        <>
          <div className="flex justify-end pb-2">
            <div className="pb-1 mr-4"> Total:</div>
            <div className="w-[60px]  text-right">
              {useParseFloat(grandTotal)}
            </div>
          </div>
          <div className="flex border-t dark:border-gray-500 justify-end border-gray-900 pb-2">
            <div className="pt-1 mr-4"> Amount Paid:</div>
            <div className="pb-1 w-[60px]  text-right">
              {useParseFloat(totalPaid)}
            </div>
          </div>
          <div className="flex border-t dark:border-gray-500 justify-end border-gray-900">
            <div className="pt-1 mr-4"> Amount Due:</div>
            <div className="pt-1 w-[60px]  text-right">
              {useParseFloat(totalDue)}
            </div>
          </div>
        </>
      ) : (
        <div className="flex justify-end border-t dark:border-gray-500 border-gray-900 pb-2">
          <div className="mr-4"> Amount Paid:</div>
          <div className="w-[60px]  text-right">
            {useParseFloat(grandTotal)}
          </div>
        </div>
      )}
      <div className="flex justify-center font-semibold text-md mt-4">
        <p>Thank You</p>
      </div>
    </div>
  );
};


export default BulkInvoicePrint;
