// Unified Invoice PDF Component
// Consolidates PrintInvoice, PdfInvoice, and InvoicePdfGenerator into one reusable component
// Supports: Print, Download PDF, Share to WhatsApp - all with proper Marathi font support

import React, { useState, useCallback } from 'react';
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';
import { Printer, Download, Share2, X, FileText } from 'lucide-react';
import { Transaction } from '../types';
import { useToast } from '../context/ToastContext';
import InvoiceBody from './InvoiceBody';

// Import shared utilities
import {
    formatINR,
    formatDate,
    getInvoiceMeta,
    calculateInvoiceTotals,
    getDisplayItems,
    formatPotiWeights,
    calculatePaidAmount,
    generateSafeFileName,
    getPaymentBreakdown,
    getPaymentModeLabel,
    InvoiceTotals,
    GroupedInvoiceItem
} from '../utils/invoiceUtils';

import {
    loadDevanagariFonts,
    applyDevanagariFont,
    renderMarathiText
} from '../utils/pdfFonts';

// ============================================
// TYPES
// ============================================

export type InvoiceAction = 'print' | 'download' | 'share';

export interface InvoicePDFProps {
    transaction: Transaction;
    className?: string;
    buttonLabel?: string;
    showIcon?: boolean;
    defaultAction?: InvoiceAction;
    onActionComplete?: (action: InvoiceAction, success: boolean) => void;
}

interface InvoicePDFState {
    showPreview: boolean;
    isGenerating: boolean;
    isSharing: boolean;
}

// ============================================
// COMPONENT
// ============================================

export const InvoicePDF: React.FC<InvoicePDFProps> = ({
    transaction,
    className,
    buttonLabel,
    showIcon = true,
    defaultAction = 'print',
    onActionComplete
}) => {
    const [state, setState] = useState<InvoicePDFState>({
        showPreview: false,
        isGenerating: false,
        isSharing: false
    });

    const toast = useToast();

    // Calculate invoice data using shared utilities
    const meta = getInvoiceMeta(transaction);
    const totals = calculateInvoiceTotals(transaction);
    const displayItems = getDisplayItems(transaction); // NO GROUPING
    const paymentInfo = getPaymentBreakdown(transaction);

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

    const generatePDF = useCallback(async (): Promise<jsPDF> => {
        // Load fonts first
        await loadDevanagariFonts();

        const doc = new jsPDF({
            orientation: 'portrait',
            unit: 'mm',
            format: 'a5'
        });

        // === HEADER ===
        doc.setFontSize(24);
        doc.setFont('helvetica', 'bold');
        doc.text('INVOICE', 14, 20);

        // Bill No and Date
        doc.setFontSize(14);
        doc.setFont('helvetica', 'bold');
        doc.text(`Bill No: ${transaction.bill_number}`, 140, 15, { align: 'right' });
        
        doc.setFontSize(12);
        doc.setFont('helvetica', 'normal');
        doc.text(`Date: ${formatDate(transaction.bill_date)} (${meta.billTypeLabel})`, 140, 22, { align: 'right' });

        // Header line
        doc.setLineWidth(2);
        doc.line(14, 28, 140, 28);

        // === BILLED TO — BIGGER PARTY NAME ===
        doc.setFontSize(10);
        doc.setFont('helvetica', 'bold');
        doc.setTextColor(85, 85, 85);
        doc.text('BILLED TO', 14, 38);
        doc.setLineWidth(0.5);
        doc.line(14, 39, 45, 39);

        doc.setTextColor(0, 0, 0);
        doc.setFontSize(22); // BIGGER
        doc.setFont('helvetica', 'bold');
        doc.text(transaction.party_name || '-', 14, 48);

        const partyPhone = (transaction as any).party_phone;
        if (partyPhone) {
            doc.setFontSize(11);
            doc.setFont('helvetica', 'normal');
            doc.setTextColor(85, 85, 85);
            doc.text(`Phone: ${partyPhone}`, 14, 55);
            doc.setTextColor(0, 0, 0);
        }

        // === ITEMS TABLE — NO GROUPING ===
        const tableData = displayItems.map((item, idx) => {
            const potiWeights = formatPotiWeights(item);
            const amount = item.net_weight * item.rate_per_kg;
            return [
                idx + 1,
                `${item.mirchi_name}\nWeights: ${potiWeights}`,
                item.poti_count,
                item.net_weight.toFixed(2),
                formatINR(item.rate_per_kg),
                formatINR(amount)
            ];
        });

        autoTable(doc, {
            startY: 60,
            head: [['#', 'मिरची', 'पोती', 'वजन', 'दर', 'एकूण रक्कम']],
            body: tableData,
            theme: 'grid',
            styles: { 
                fontSize: 10, 
                cellPadding: 4, 
                lineWidth: 0.5, 
                lineColor: [0, 0, 0],
                font: 'NotoSansDevanagari'
            },
            headStyles: { 
                fillColor: [255, 255, 255], 
                textColor: [0, 0, 0], 
                fontStyle: 'bold', 
                fontSize: 12 
            },
            bodyStyles: { textColor: [0, 0, 0] },
            columnStyles: {
                0: { halign: 'center', cellWidth: 10 },
                1: { halign: 'left', cellWidth: 45 },
                2: { halign: 'center', cellWidth: 15 },
                3: { halign: 'center', cellWidth: 20 },
                4: { halign: 'right', cellWidth: 20 },
                5: { halign: 'right', cellWidth: 22 }
            }
        });

        const finalY = (doc as any).lastAutoTable.finalY + 10;

        // === SUMMARY TABLE ===
        const summaryData: string[][] = [
            ['पॅकिंग', formatINR(totals.packing)],
            ['एकूण रक्कम', formatINR(totals.subtotal + totals.packing)]
        ];

        if (totals.cess > 0) summaryData.push(['सेस', formatINR(totals.cess)]);
        if (totals.adat > 0) summaryData.push(['अडत', formatINR(totals.adat)]);
        if (totals.hamali > 0) summaryData.push(['हमाली', formatINR(totals.hamali)]);
        if (totals.gaadiBharni > 0) summaryData.push(['गाडी भाडे', formatINR(totals.gaadiBharni)]);
        if (totals.otherExpenses > 0) summaryData.push(['इतर खर्च', formatINR(totals.otherExpenses)]);
        summaryData.push(['पूर्ण रक्कम', formatINR(totals.grandTotal)]);

        // Append Payments to Summary Data
        const { payments: payBreakdown, totalPaid, totalDue, isPartial } = paymentInfo;

        if (payBreakdown.length > 0) {
            summaryData.push([isPartial ? 'जमा (Partial)' : 'जमा', formatINR(totalPaid)]);
            payBreakdown.forEach(p => {
                summaryData.push([`  ${p.modeLabel} ${p.reference ? `(${p.reference})` : ''}`, formatINR(p.amount)]);
            });
        } else {
            summaryData.push(['जमा', formatINR(0)]);
        }

        if (totalDue > 0) {
            summaryData.push(['येणे बाकी', formatINR(totalDue)]);
        }

        autoTable(doc, {
            startY: finalY,
            body: summaryData,
            theme: 'grid',
            styles: { 
                fontSize: 10, 
                cellPadding: 3, 
                lineWidth: 0.5, 
                lineColor: [200, 200, 200],
                font: 'NotoSansDevanagari'
            },
            bodyStyles: { textColor: [0, 0, 0] },
            columnStyles: {
                0: { halign: 'left', cellWidth: 35 },
                1: { halign: 'right', cellWidth: 30 }
            },
            margin: { left: 85 }
        });

        return doc;
    }, [transaction, meta, totals, displayItems, paymentInfo]);

    // ============================================
    // ACTIONS
    // ============================================

    const handlePrint = useCallback(async () => {
        setState(prev => ({ ...prev, isGenerating: true }));
        try {
            const doc = await generatePDF();
            doc.autoPrint();
            window.open(doc.output('bloburl'), '_blank');
            toast.success('Invoice sent to printer');
            onActionComplete?.('print', true);
        } catch (error) {
            console.error('Print failed:', error);
            toast.error('Print failed', 'Please try again');
            onActionComplete?.('print', false);
        } finally {
            setState(prev => ({ ...prev, isGenerating: false }));
        }
    }, [generatePDF, toast, onActionComplete]);

    const handleDownload = useCallback(async () => {
        setState(prev => ({ ...prev, isGenerating: true }));
        try {
            const doc = await generatePDF();
            const fileName = generateSafeFileName(
                transaction.party_name || 'Party',
                transaction.bill_number,
                'Invoice'
            );
            doc.save(fileName);
            toast.success('Invoice downloaded');
            onActionComplete?.('download', true);
        } catch (error) {
            console.error('Download failed:', error);
            toast.error('Download failed', 'Please try again');
            onActionComplete?.('download', false);
        } finally {
            setState(prev => ({ ...prev, isGenerating: false }));
        }
    }, [generatePDF, transaction, toast, onActionComplete]);

    const handleShare = useCallback(async () => {
        setState(prev => ({ ...prev, isSharing: true }));
        try {
            const doc = await generatePDF();
            const pdfBlob = doc.output('blob');
            const fileName = generateSafeFileName(
                transaction.party_name || 'Party',
                transaction.bill_number,
                'Invoice'
            );

            // Try Web Share API first
            if (navigator.share) {
                try {
                    const file = new File([pdfBlob], fileName, { type: 'application/pdf' });
                    if (navigator.canShare && navigator.canShare({ files: [file] })) {
                        await navigator.share({
                            files: [file],
                            title: `Invoice ${transaction.bill_number}`,
                            text: `Invoice for ${transaction.party_name || 'Customer'} - Bill #${transaction.bill_number}`
                        });
                        toast.success('Invoice shared');
                        onActionComplete?.('share', true);
                        return;
                    }
                } catch (err: any) {
                    if (err.name === 'AbortError') {
                        // User cancelled
                        return;
                    }
                }
            }

            // Fallback: download + WhatsApp link
            const url = URL.createObjectURL(pdfBlob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            a.click();
            URL.revokeObjectURL(url);

            const text = encodeURIComponent(
                `Invoice #${transaction.bill_number}\nType: ${meta.isMixed ? 'Mixed' : (meta.isPatti ? 'Patti' : 'Regular')}\nParty: ${transaction.party_name || ''}\nAmount: ₹${Math.round(totals.grandTotal).toLocaleString()}\nDate: ${formatDate(transaction.bill_date)}\n\nPlease find the invoice attached.`
            );
            window.open(`https://wa.me/?text=${text}`, '_blank');
            
            toast.success('Invoice downloaded', 'Share via WhatsApp opened');
            onActionComplete?.('share', true);
        } catch (error) {
            console.error('Share failed:', error);
            toast.error('Share failed', 'Please try again');
            onActionComplete?.('share', false);
        } finally {
            setState(prev => ({ ...prev, isSharing: false }));
        }
    }, [generatePDF, transaction, meta, totals, toast, onActionComplete]);

    // ============================================
    // RENDER
    // ============================================

    return (
        <>
            <button
                onClick={() => setState(prev => ({ ...prev, showPreview: true }))}
                className={className || "p-2 bg-white text-teal-600 border border-teal-600 rounded-md hover:bg-teal-50 transition-colors flex items-center justify-center gap-2 shadow-sm"}
                title="Invoice Options"
            >
                {showIcon && <FileText size={16} />}
                {buttonLabel && <span>{buttonLabel}</span>}
            </button>

            {state.showPreview && (
                <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-2 sm:p-4">
                    <div className="bg-white rounded-lg shadow-2xl max-w-4xl w-full max-h-[95vh] sm:max-h-[90vh] overflow-hidden flex flex-col">

                        {/* Header */}
                        <div className="sticky top-0 bg-white border-b border-gray-200 px-3 py-3 sm:px-6 sm:py-4 flex justify-between items-center z-10 shrink-0">
                            <h2 className="text-lg sm:text-xl font-bold text-gray-800 truncate mr-2">
                                Invoice Preview - {transaction.bill_number}
                            </h2>
                            <div className="flex gap-2 items-center">
                                <button
                                    onClick={handleShare}
                                    disabled={state.isSharing}
                                    className="px-3 py-1.5 sm:px-4 sm:py-2 text-sm sm:text-base bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors flex items-center gap-1 sm:gap-2 disabled:opacity-50"
                                >
                                    {state.isSharing ? (
                                        <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24">
                                            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
                                            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                                        </svg>
                                    ) : (
                                        <Share2 size={16} />
                                    )}
                                    <span className="hidden sm:inline">Share</span>
                                </button>
                                <button
                                    onClick={handleDownload}
                                    disabled={state.isGenerating}
                                    className="px-3 py-1.5 sm:px-4 sm:py-2 text-sm sm:text-base bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors flex items-center gap-1 sm:gap-2 disabled:opacity-50"
                                >
                                    {state.isGenerating ? (
                                        <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24">
                                            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
                                            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                                        </svg>
                                    ) : (
                                        <Download size={16} />
                                    )}
                                    <span className="hidden sm:inline">Download</span>
                                </button>
                                <button
                                    onClick={handlePrint}
                                    disabled={state.isGenerating}
                                    className="px-3 py-1.5 sm:px-4 sm:py-2 text-sm sm:text-base bg-teal-600 text-white rounded-lg hover:bg-teal-700 transition-colors flex items-center gap-1 sm:gap-2 disabled:opacity-50"
                                >
                                    <Printer size={16} />
                                    <span className="hidden sm:inline">Print</span>
                                </button>
                                <button
                                    onClick={() => setState(prev => ({ ...prev, showPreview: false }))}
                                    className="p-1.5 sm:p-2 hover:bg-gray-100 rounded-lg transition-colors"
                                >
                                    <X size={20} className="text-gray-600" />
                                </button>
                            </div>
                        </div>

                        {/* Preview Content — Uses SAME InvoiceBody */}
                        <div className="overflow-auto flex-1 p-2 sm:p-8 bg-gray-100">
                            <InvoiceBody transaction={transaction} />
                        </div>
                    </div>
                </div>
            )}
        </>
    );
};

export default InvoicePDF;
