import PDFDocument from "pdfkit";
import type { Response } from "express";
import { PdfHeader } from "./components/PdfHeader.js";

const COLORS = {
    primary: "#1E293B",
    secondary: "#0F5132",
    accent: "#198754",
    text: "#212529",
    muted: "#6C757D",
    border: "#94A3B8",
    lightBorder: "#CBD5E1",
    rowAlt: "#F8F9FA",
    headerBg: "#0F172A",
    subHeaderBg: "#1E293B",
    greenRow: "#D1E7DD",
    mintRow: "#A7F3D0",
    blueRow: "#DBEAFE",
    totalRowBg: "#ECFDF5",
    white: "#FFFFFF",
    emeraldText: "#047857",
    darkGreenText: "#15803D",
    redText: "#DC2626",
    blueText: "#1D4ED8",
    purpleText: "#6B21A8",
    purpleBg: "#F3E8FF",
    blueBadgeBg: "#EFF6FF",
};

const PAGE_MARGIN = 25;

function fmt(val: number | undefined | null): string {
    const n = Number(val ?? 0);
    return isNaN(n) ? "0.00" : n.toLocaleString("en-IN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

function fmtQty(val: number | undefined | null): string {
    const n = Number(val ?? 0);
    return isNaN(n) ? "0.000" : n.toLocaleString("en-IN", { minimumFractionDigits: 3, maximumFractionDigits: 3 });
}

export class WholesaleDailySummaryPdf {
    static async generate(data: any, res: Response) {
        const doc = new PDFDocument({
            size: "A4",
            layout: "landscape",
            margin: PAGE_MARGIN,
            bufferPages: true,
        });

        res.setHeader("Content-Type", "application/pdf");
        res.setHeader(
            "Content-Disposition",
            `inline; filename="wholesale-daily-summary-${data.financialSummary?.date || Date.now()}.pdf"`
        );
        res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        doc.pipe(res);

        const pageWidth = doc.page.width - PAGE_MARGIN * 2;

        await PdfHeader.draw(doc, pageWidth, PAGE_MARGIN, "WHOLESALE DAILY SUMMARY & FINANCIAL REPORT");

        this.drawFinancialSummaryCard(doc, pageWidth, data.financialSummary);
        
        this.drawWholesaleItemizedTable(doc, pageWidth, data.wholesaleItemized || []);
        
        if (data.stockMovements && data.stockMovements.length > 0) {
            this.drawStockMovementsTable(doc, pageWidth, data.stockMovements);
        }

        this.drawFooter(doc, pageWidth);
        doc.end();
    }

    private static formatDate(dateStr?: string): string {
        if (!dateStr) return new Date().toLocaleDateString("en-GB").replace(/\//g, "-");
        const parts = dateStr.split("-");
        if (parts.length === 3) {
            return `${parts[2]}.${parts[1]}.${parts[0]}`;
        }
        return dateStr;
    }

    private static drawFinancialSummaryCard(doc: PDFKit.PDFDocument, pageWidth: number, summary: any) {
        const cardX = PAGE_MARGIN;
        const cardY = doc.y + 4;
        const colWidth = pageWidth / 2;
        const rowHeight = 16.5;

        const sales = summary?.sales ?? summary?.opening?.sales ?? 0;
        const cogs = summary?.cogs ?? summary?.opening?.cogs ?? 0;
        const grossAmount = summary?.grossAmount ?? summary?.opening?.grossAmount ?? 0;
        const expenses = summary?.expenses ?? summary?.opening?.expenses ?? 0;
        const profit = summary?.profit ?? summary?.opening?.profit ?? 0;
        const salesCollection = summary?.salesCollection ?? summary?.closing?.salesCollection ?? 0;
        const supplierCollection = summary?.supplierCollection ?? summary?.closing?.supplierCollection ?? 0;
        const purchasesTotal = summary?.purchasesTotal ?? summary?.closing?.purchase ?? 0;
        const customerOutstanding = summary?.customerOutstanding ?? summary?.opening?.outstanding ?? 0;
        const supplierOutstanding = summary?.supplierOutstanding ?? summary?.closing?.outstanding ?? 0;

        const bannerHeight = 30;
        const formattedDate = this.formatDate(summary?.date);

        // Dark Banner
        doc.rect(cardX, cardY, pageWidth, bannerHeight).fill(COLORS.headerBg);

        doc.font("Helvetica-Bold")
            .fontSize(8)
            .fillColor("#94A3B8")
            .text(`Date : ${formattedDate}`, cardX, cardY + 4, { width: pageWidth, align: "center", lineBreak: false });

        doc.font("Helvetica-Bold")
            .fontSize(10)
            .fillColor(COLORS.white)
            .text("FINANCIAL SUMMARY (WHOLESALE)", cardX, cardY + 15, { width: pageWidth, align: "center", lineBreak: false });

        let currentY = cardY + bannerHeight;

        // Grid Header
        doc.rect(cardX, currentY, colWidth, rowHeight).fill(COLORS.subHeaderBg);
        doc.rect(cardX + colWidth, currentY, colWidth, rowHeight).fill(COLORS.subHeaderBg);

        doc.font("Helvetica-Bold")
            .fontSize(8.5)
            .fillColor(COLORS.white)
            .text("WHOLESALE METRICS", cardX, currentY + 4, { width: colWidth, align: "center", lineBreak: false })
            .text("AMOUNT / VALUE", cardX + colWidth, currentY + 4, { width: colWidth, align: "center", lineBreak: false });

        currentY += rowHeight;

        const rows = [
            { label: "Total Wholesale Sales Revenue", val: `Rs.${fmt(sales)}`, bold: true, isEmerald: true },
            // { label: "Cost of Goods Sold (COGS)", val: `Rs.${fmt(cogs)}` },
            { label: "Gross Profit Amount", val: `Rs.${fmt(grossAmount)}`, bg: COLORS.greenRow, bold: true, isEmerald: true },
            { label: "Total Wholesale Expenses", val: `Rs.${fmt(expenses)}`, isRed: true },
            { label: "NET WHOLESALE PROFIT", val: `Rs.${fmt(profit)}`, bg: COLORS.mintRow, bold: true, isEmerald: true },
            { label: "Today's Customer Receipts (Collection)", val: `Rs.${fmt(salesCollection)}`, isBlue: true, bold: true },
            { label: "Today's Supplier Payments", val: `Rs.${fmt(supplierCollection)}` },
            { label: "Today's Total Purchases", val: `Rs.${fmt(purchasesTotal)}` },
            { label: "Total Customer Outstanding Balance", val: `Rs.${fmt(customerOutstanding)}`, bg: COLORS.rowAlt, bold: true },
            { label: "Total Supplier Outstanding Balance", val: `Rs.${fmt(supplierOutstanding)}`, bg: COLORS.rowAlt, bold: true },
        ];

        for (const row of rows) {
            if (row.bg) {
                doc.rect(cardX, currentY, pageWidth, rowHeight).fill(row.bg);
            }

            doc.rect(cardX, currentY, colWidth, rowHeight).stroke(COLORS.lightBorder);
            doc.rect(cardX + colWidth, currentY, colWidth, rowHeight).stroke(COLORS.lightBorder);

            const fontName = row.bold ? "Helvetica-Bold" : "Helvetica";
            doc.font(fontName).fontSize(8).fillColor(COLORS.text);

            doc.text(row.label, cardX + 8, currentY + 4, { width: colWidth - 12, align: "left", lineBreak: false });

            if (row.isEmerald) doc.font("Helvetica-Bold").fillColor(COLORS.emeraldText);
            else if (row.isRed) doc.fillColor(COLORS.redText);
            else if (row.isBlue) doc.font("Helvetica-Bold").fillColor(COLORS.blueText);
            else doc.fillColor(COLORS.text);

            doc.text(row.val, cardX + colWidth + 8, currentY + 4, { width: colWidth - 16, align: "right", lineBreak: false });

            currentY += rowHeight;
        }

        doc.rect(cardX, cardY, pageWidth, currentY - cardY).stroke(COLORS.border);

        doc.y = currentY + 12;
    }

    private static drawWholesaleItemizedTable(doc: PDFKit.PDFDocument, pageWidth: number, items: any[]) {
        const titleH = 16;
        const headerH = 18;
        const rowH = 16.5;

        if (doc.y + titleH + headerH + rowH > doc.page.height - PAGE_MARGIN - 20) {
            doc.addPage();
        }

        doc.font("Helvetica-Bold").fontSize(10).fillColor(COLORS.primary).text("Wholesale Sales Itemised Profit Breakdown", PAGE_MARGIN, doc.y, { lineBreak: false });
        doc.y += 14;

        const cols = {
            no: { x: PAGE_MARGIN, width: 30 },
            invoiceNo: { x: PAGE_MARGIN + 30, width: 110 },
            customer: { x: PAGE_MARGIN + 140, width: 100 },
            veg: { x: PAGE_MARGIN + 240, width: 90 },
            lotNo: { x: PAGE_MARGIN + 330, width: 80 },
            qty: { x: PAGE_MARGIN + 410, width: 60 },
            costRate: { x: PAGE_MARGIN + 470, width: 65 },
            sellRate: { x: PAGE_MARGIN + 535, width: 65 },
            totalAmt: { x: PAGE_MARGIN + 600, width: 70 },
            costTotal: { x: PAGE_MARGIN + 670, width: 65 },
            profit: { x: PAGE_MARGIN + 735, width: 56.89 },
        };

        const drawHeader = () => {
            const y = doc.y;
            doc.rect(PAGE_MARGIN, y, pageWidth, headerH).fill(COLORS.subHeaderBg);
            doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.white);

            doc.text("#", cols.no.x, y + 5, { width: cols.no.width, align: "center", lineBreak: false })
                .text("Invoice No", cols.invoiceNo.x + 4, y + 5, { width: cols.invoiceNo.width - 4, align: "left", lineBreak: false })
                .text("Customer", cols.customer.x, y + 5, { width: cols.customer.width, align: "left", lineBreak: false })
                .text("Vegetable", cols.veg.x, y + 5, { width: cols.veg.width, align: "left", lineBreak: false })
                .text("Lot No", cols.lotNo.x, y + 5, { width: cols.lotNo.width, align: "left", lineBreak: false })
                .text("Qty Sold", cols.qty.x, y + 5, { width: cols.qty.width - 2, align: "right", lineBreak: false })
                .text("Cost Price", cols.costRate.x, y + 5, { width: cols.costRate.width - 2, align: "right", lineBreak: false })
                .text("Sell Rate", cols.sellRate.x, y + 5, { width: cols.sellRate.width - 2, align: "right", lineBreak: false })
                .text("Sales Amount", cols.totalAmt.x, y + 5, { width: cols.totalAmt.width - 2, align: "right", lineBreak: false })
                .text("Cost Total", cols.costTotal.x, y + 5, { width: cols.costTotal.width - 2, align: "right", lineBreak: false })
                .text("Profit", cols.profit.x, y + 5, { width: cols.profit.width - 2, align: "right", lineBreak: false });

            doc.y = y + headerH;
        };

        drawHeader();

        let sumQty = 0;
        let sumSales = 0;
        let sumCostTotal = 0;
        let sumProfit = 0;

        items.forEach((item: any, idx: number) => {
            if (doc.y + rowH > doc.page.height - PAGE_MARGIN - 20) {
                doc.addPage();
                drawHeader();
            }

            const y = doc.y;
            if (idx % 2 === 1) {
                doc.rect(PAGE_MARGIN, y, pageWidth, rowH).fill(COLORS.rowAlt);
            }

            const isArrival = !!item.isArrival;
            const isFlexible = !isArrival && (!!item.isFlexible || item.unit === "PIECES");
            sumQty += Number(item.quantity || 0);
            sumSales += Number(item.totalAmt || 0);
            if (!isFlexible) {
                sumCostTotal += Number(item.costTotal || 0);
                sumProfit += Number(item.profit || 0);
            }

            doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text);

            doc.text(String(idx + 1), cols.no.x, y + 4, { width: cols.no.width, align: "center", lineBreak: false });

            // Invoice No badge
            if (item.invoiceNo) {
                doc.roundedRect(cols.invoiceNo.x + 2, y + 2, cols.invoiceNo.width - 6, 12.5, 3).fill(COLORS.blueBadgeBg);
                doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.blueText)
                    .text(item.invoiceNo, cols.invoiceNo.x + 4, y + 4, { width: cols.invoiceNo.width - 10, align: "left", lineBreak: false });
            } else {
                doc.text("-", cols.invoiceNo.x + 4, y + 4, { width: cols.invoiceNo.width - 4, align: "left", lineBreak: false });
            }

            doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text)
                .text(item.customerName || "-", cols.customer.x, y + 4, { width: cols.customer.width, align: "left", lineBreak: false })
                .text(item.vegetableName || "-", cols.veg.x, y + 4, { width: cols.veg.width, align: "left", lineBreak: false });

            // Lot No badge
            if (item.lotNo && item.lotNo !== "-") {
                doc.roundedRect(cols.lotNo.x, y + 2, cols.lotNo.width - 10, 12.5, 3).fill(COLORS.purpleBg);
                doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.purpleText)
                    .text(item.lotNo, cols.lotNo.x + 4, y + 4, { width: cols.lotNo.width - 18, align: "center", lineBreak: false });
            } else {
                doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text)
                    .text("-", cols.lotNo.x, y + 4, { width: cols.lotNo.width, align: "left", lineBreak: false });
            }

            doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.text)
                .text(fmtQty(item.quantity), cols.qty.x, y + 4, { width: cols.qty.width - 2, align: "right", lineBreak: false });

            doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text)
                .text((isArrival || isFlexible) ? "-" : fmt(item.costPerUnit), cols.costRate.x, y + 4, { width: cols.costRate.width - 2, align: "right", lineBreak: false })
                .text(fmt(item.sellingRate), cols.sellRate.x, y + 4, { width: cols.sellRate.width - 2, align: "right", lineBreak: false });

            // Sales Amount (Rs.) (Emerald)
            doc.font("Helvetica-Bold").fillColor(COLORS.emeraldText)
                .text(`Rs.${fmt(item.totalAmt)}`, cols.totalAmt.x, y + 4, { width: cols.totalAmt.width - 2, align: "right", lineBreak: false });

            // Cost Total (Rs.)
            if (isFlexible) {
                doc.font("Helvetica").fillColor(COLORS.text)
                    .text("-", cols.costTotal.x, y + 4, { width: cols.costTotal.width - 2, align: "right", lineBreak: false });
            } else {
                doc.font("Helvetica").fillColor(COLORS.text)
                    .text(`Rs.${fmt(item.costTotal)}`, cols.costTotal.x, y + 4, { width: cols.costTotal.width - 2, align: "right", lineBreak: false });
            }

            // Profit (Rs.)
            if (isFlexible) {
                doc.font("Helvetica").fillColor(COLORS.text)
                    .text("-", cols.profit.x, y + 4, { width: cols.profit.width - 2, align: "right", lineBreak: false });
            } else {
                const profitVal = Number(item.profit || 0);
                doc.font("Helvetica-Bold").fillColor(profitVal >= 0 ? COLORS.darkGreenText : COLORS.redText)
                    .text(`Rs.${fmt(profitVal)}`, cols.profit.x, y + 4, { width: cols.profit.width - 2, align: "right", lineBreak: false });
            }

            doc.rect(PAGE_MARGIN, y, pageWidth, rowH).stroke(COLORS.lightBorder);
            doc.y = y + rowH;
        });

        // Totals Row
        if (doc.y + rowH > doc.page.height - PAGE_MARGIN - 20) {
            doc.addPage();
            drawHeader();
        }

        const totY = doc.y;
        doc.rect(PAGE_MARGIN, totY, pageWidth, rowH + 2).fill(COLORS.totalRowBg);
        doc.font("Helvetica-Bold").fontSize(8).fillColor(COLORS.primary);
        doc.text("TOTAL:", cols.no.x, totY + 5, { width: cols.lotNo.x + cols.lotNo.width - cols.no.x - 6, align: "right", lineBreak: false });
        doc.text(fmtQty(sumQty), cols.qty.x, totY + 5, { width: cols.qty.width - 2, align: "right", lineBreak: false });
        
        doc.fillColor(COLORS.emeraldText).text(`Rs.${fmt(sumSales)}`, cols.totalAmt.x, totY + 5, { width: cols.totalAmt.width - 2, align: "right", lineBreak: false });
        doc.fillColor(COLORS.primary).text(`Rs.${fmt(sumCostTotal)}`, cols.costTotal.x, totY + 5, { width: cols.costTotal.width - 2, align: "right", lineBreak: false });
        doc.fillColor(COLORS.darkGreenText).text(`Rs.${fmt(sumProfit)}`, cols.profit.x, totY + 5, { width: cols.profit.width - 2, align: "right", lineBreak: false });

        doc.rect(PAGE_MARGIN, totY, pageWidth, rowH + 2).stroke(COLORS.border);
        doc.y = totY + rowH + 12;
    }

    private static drawStockMovementsTable(doc: PDFKit.PDFDocument, pageWidth: number, movements: any[]) {
        const titleH = 16;
        const headerH = 18;
        const rowH = 16.5;

        if (doc.y + titleH + headerH + rowH > doc.page.height - PAGE_MARGIN - 20) {
            doc.addPage();
        }

        doc.font("Helvetica-Bold").fontSize(10).fillColor(COLORS.primary).text("Daily Stock Movements (Purchased vs Sold & Retail Transfer)", PAGE_MARGIN, doc.y, { lineBreak: false });
        doc.y += 14;

        const cols = {
            lotNo: { x: PAGE_MARGIN, width: 75 },
            veg: { x: PAGE_MARGIN + 75, width: 130 },
            supplier: { x: PAGE_MARGIN + 205, width: 130 },
            purchased: { x: PAGE_MARGIN + 335, width: 95 },
            sold: { x: PAGE_MARGIN + 430, width: 110 },
            retailMoved: { x: PAGE_MARGIN + 540, width: 115 },
            remaining: { x: PAGE_MARGIN + 655, width: 136.89 },
        };

        const drawHeader = () => {
            const y = doc.y;
            doc.rect(PAGE_MARGIN, y, pageWidth, headerH).fill(COLORS.subHeaderBg);
            doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.white);

            doc.text("Lot No", cols.lotNo.x + 4, y + 5, { width: cols.lotNo.width - 4, align: "left", lineBreak: false })
                .text("Vegetable", cols.veg.x, y + 5, { width: cols.veg.width, align: "left", lineBreak: false })
                .text("Supplier", cols.supplier.x, y + 5, { width: cols.supplier.width, align: "left", lineBreak: false })
                .text("Purchased Qty", cols.purchased.x, y + 5, { width: cols.purchased.width - 4, align: "right", lineBreak: false })
                .text("Wholesale Sold Qty", cols.sold.x, y + 5, { width: cols.sold.width - 4, align: "right", lineBreak: false })
                .text("Moved to Retail", cols.retailMoved.x, y + 5, { width: cols.retailMoved.width - 4, align: "right", lineBreak: false })
                .text("Remaining Stock Qty", cols.remaining.x, y + 5, { width: cols.remaining.width - 4, align: "right", lineBreak: false });

            doc.y = y + headerH;
        };

        drawHeader();

        movements.forEach((m: any, idx: number) => {
            if (doc.y + rowH > doc.page.height - PAGE_MARGIN - 20) {
                doc.addPage();
                drawHeader();
            }

            const rowY = doc.y;
            if (idx % 2 === 1) doc.rect(PAGE_MARGIN, rowY, pageWidth, rowH).fill(COLORS.rowAlt);

            // Lot No badge
            if (m.lotNo && m.lotNo !== "-") {
                doc.roundedRect(cols.lotNo.x + 2, rowY + 2, cols.lotNo.width - 10, 12.5, 3).fill(COLORS.purpleBg);
                doc.font("Helvetica-Bold").fontSize(7.5).fillColor(COLORS.purpleText)
                    .text(m.lotNo, cols.lotNo.x + 4, rowY + 4, { width: cols.lotNo.width - 14, align: "center", lineBreak: false });
            } else {
                doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text)
                    .text("-", cols.lotNo.x + 4, rowY + 4, { width: cols.lotNo.width - 4, align: "left", lineBreak: false });
            }

            doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.text);
            doc.text(m.vegetableName || "-", cols.veg.x, rowY + 4, { width: cols.veg.width, align: "left", lineBreak: false })
                .text(m.supplierName || "-", cols.supplier.x, rowY + 4, { width: cols.supplier.width, align: "left", lineBreak: false })
                .text(fmtQty(m.purchasedQty), cols.purchased.x, rowY + 4, { width: cols.purchased.width - 4, align: "right", lineBreak: false });

            const soldVal = fmtQty(m.wholesaleSoldQty ?? m.soldQty);
            const soldText = m.secondarySoldText ? `${soldVal} (+${m.secondarySoldText})` : soldVal;

            doc.font("Helvetica-Bold").fillColor(COLORS.blueText)
                .text(soldText, cols.sold.x, rowY + 4, { width: cols.sold.width - 4, align: "right", lineBreak: false });

            doc.font("Helvetica-Bold").fillColor("#D97706")
                .text(fmtQty(m.retailMovedQty || 0), cols.retailMoved.x, rowY + 4, { width: cols.retailMoved.width - 4, align: "right", lineBreak: false });

            doc.font("Helvetica-Bold").fillColor(COLORS.darkGreenText)
                .text(fmtQty(m.remainingQty), cols.remaining.x, rowY + 4, { width: cols.remaining.width - 4, align: "right", lineBreak: false });

            doc.rect(PAGE_MARGIN, rowY, pageWidth, rowH).stroke(COLORS.lightBorder);
            doc.y = rowY + rowH;
        });
    }

    private static drawFooter(doc: PDFKit.PDFDocument, pageWidth: number) {
        const pages = doc.bufferedPageRange();
        for (let i = 0; i < pages.count; i++) {
            doc.switchToPage(i);

            const oldBottomMargin = doc.page.margins.bottom;
            doc.page.margins.bottom = 0;

            const footerY = doc.page.height - 18;
            doc.font("Helvetica").fontSize(7.5).fillColor(COLORS.muted)
                .text(`Generated on ${new Date().toLocaleString("en-IN")}`, PAGE_MARGIN, footerY, {
                    width: pageWidth,
                    align: "left",
                    lineBreak: false,
                });

            doc.page.margins.bottom = oldBottomMargin;
        }
    }
}
