import React, { useEffect, useState, useCallback } from "react";
import { useParams, useNavigate, useSearchParams } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
    Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { ArrowLeft, Printer, MessageCircle, FileJson, Truck, Send, FileDown, Receipt, Pencil, MapPin, Share2 } from "lucide-react";
import { downloadInvoicePDF, thermalPrint } from "@/lib/printing";
import { getPrintSettings, getTemplate } from "@/lib/printSettings";
import { openInGoogleMaps } from "@/components/maps/mapHelpers";
import SecureUpiQR from "@/components/SecureUpiQR";
import SharePanel from "@/components/SharePanel";
import { api } from "@/lib/api";
import { formatINR, formatDate } from "@/lib/format";
import { useCompany } from "@/context/CompanyContext";
import { useI18n } from "@/context/I18nContext";
import { amountInWords } from "@/lib/words";
import { toast } from "sonner";

export default function InvoiceView() {
    const { id } = useParams();
    const navigate = useNavigate();
    const [search] = useSearchParams();
    const { active } = useCompany();
    const { t } = useI18n();
    const [inv, setInv] = useState(null);
    const [twilio, setTwilio] = useState(null);
    const [sendOpen, setSendOpen] = useState(false);
    const [sendChannel, setSendChannel] = useState("whatsapp");
    const [sendTo, setSendTo] = useState("");
    const [sendBody, setSendBody] = useState("");
    const [sending, setSending] = useState(false);
    const [party, setParty] = useState(null);
    const [shareOpen, setShareOpen] = useState(false);
    const [shareUrl, setShareUrl] = useState("");
    const [shareMessage, setShareMessage] = useState("");

    const openSharePanel = useCallback(async () => {
        // Generate (or rotate) a secure share token + WhatsApp template
        try {
            const { data } = await api.post(`/invoice-share/token/${id}`);
            const publicUrl = data?.url || (typeof window !== "undefined" ? window.location.href : "");
            setShareUrl(publicUrl);
            // Apply WhatsApp template if available
            try {
                const s = await api.get("/invoice-share/settings");
                const tpl = s?.data?.wa_templates?.[inv?.type || "sale"] || "";
                if (tpl) {
                    const filled = tpl
                        .replaceAll("{customer_name}", inv?.party_name || "Customer")
                        .replaceAll("{invoice_no}", inv?.invoice_no || "")
                        .replaceAll("{total}", Number(inv?.total || 0).toFixed(2))
                        .replaceAll("{link}", publicUrl);
                    setShareMessage(filled);
                }
            } catch (_) { /* template optional */ }
        } catch (e) {
            // Fallback to in-app link
            setShareUrl(typeof window !== "undefined" ? window.location.href : "");
            toast.error(e?.response?.data?.detail || "Couldn't generate secure link — using in-app URL");
        }
        setShareOpen(true);
    }, [id, inv]);

    useEffect(() => {
        api.get(`/invoices/${id}`).then((r) => {
            setInv(r.data);
            if (search.get("print")) setTimeout(() => window.print(), 400);
            // Handle Smart Save post-action from NewInvoice
            const action = search.get("action");
            if (action === "print") setTimeout(() => window.print(), 600);
            else if (action === "share") setTimeout(() => setShareOpen(true), 600);
            else if (action === "whatsapp") setTimeout(() => openSend("whatsapp"), 600);
            else if (action === "email") setTimeout(() => openSend("email"), 600);
            // Fetch party for map button
            if (r.data?.party_id) {
                api.get(`/parties/${r.data.party_id}`).then((p) => setParty(p.data)).catch(() => {});
            }
        });
        api.get("/messaging/status").then((r) => setTwilio(r.data)).catch(() => setTwilio({ configured: false }));
    // openSend is a stable callback; intentionally not adding to deps to avoid loop
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [id, search]);

    const openSend = useCallback((channel) => {
        const balance = Math.max(0, (inv?.total || 0) - (inv?.payment_received || 0));
        const text = `Hi ${inv?.party_name || "Customer"},\n\n` +
            `Invoice ${inv?.invoice_no} from ${active?.name || "RGE Regalgoa"}\n` +
            `Date: ${formatDate(inv?.invoice_date)}\n` +
            `Total: ₹${Number(inv?.total || 0).toFixed(2)}\n` +
            `Paid: ₹${Number(inv?.payment_received || 0).toFixed(2)}\n` +
            `Balance Due: ₹${balance.toFixed(2)}\n\n` +
            `Thank you for your business!`;
        setSendBody(text);
        setSendChannel(channel);
        setSendOpen(true);
    }, [inv, active]);

    const doSend = async () => {
        setSending(true);
        try {
            await api.post(`/messaging/${sendChannel}`, { to: sendTo, body: sendBody, invoice_id: inv.id });
            toast.success(`${sendChannel === "whatsapp" ? "WhatsApp" : "SMS"} sent`);
            setSendOpen(false); setSendTo("");
        } catch (e) {
            toast.error(e.response?.data?.detail || "Failed to send");
        } finally { setSending(false); }
    };

    const downloadJson = async (kind) => {
        try {
            const { data } = await api.get(`/invoices/${id}/${kind}-json`);
            const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = url;
            a.download = `${inv.invoice_no.replace(/\//g, "-")}-${kind}.json`;
            a.click();
            URL.revokeObjectURL(url);
            toast.success(`${kind === "einvoice" ? "E-Invoice" : "E-Way bill"} JSON downloaded`);
        } catch (e) {
            toast.error("Failed to generate JSON");
        }
    };

    const shareWhatsApp = () => {
        const text = `*${active?.name || "RGE Regalgoa"}*%0A` +
            `Invoice: *${inv.invoice_no}*%0A` +
            `Date: ${formatDate(inv.invoice_date)}%0A` +
            `Total: ₹${Number(inv.total).toFixed(2)}%0A` +
            `Paid: ₹${Number(inv.payment_received).toFixed(2)}%0A` +
            `Balance: ₹${Math.max(0, inv.total - inv.payment_received).toFixed(2)}%0A%0A` +
            `Thank you for your business!`;
        const phone = ""; // user can pick contact in WhatsApp
        const url = `https://wa.me/${phone}?text=${text}`;
        window.open(url, "_blank");
    };

    const [pdfBusy, setPdfBusy] = useState(false);
    const [thermalBusy, setThermalBusy] = useState(false);

    const handlePdf = async () => {
        setPdfBusy(true);
        const tid = toast.loading("Generating invoice PDF…");
        try {
            await downloadInvoicePDF(inv, active || {});
            toast.dismiss(tid);
            toast.success("Invoice PDF downloaded");
        } catch (e) {
            toast.dismiss(tid);
            toast.error(`PDF generation failed: ${e?.message || e}`);
        } finally {
            setPdfBusy(false);
        }
    };

    const handleThermal = async () => {
        setThermalBusy(true);
        const tid = toast.loading("Preparing 80mm thermal receipt…");
        try {
            await thermalPrint(inv, active || {});
            toast.dismiss(tid);
            toast.success("Thermal receipt ready");
        } catch (e) {
            toast.dismiss(tid);
            toast.error(`Thermal print failed: ${e?.message || e}`);
        } finally {
            setThermalBusy(false);
        }
    };

    if (!inv) return <div className="text-sm text-muted-foreground">Loading…</div>;

    // Resolve current print settings + selected template — both are needed by the
    // themed invoice card below. `getTemplate(id)` ALWAYS returns a valid template
    // (falls back to the first PRINT_TEMPLATES entry when the saved id is unknown),
    // so `tpl` is never undefined and no extra null-check is required.
    const printSettings = getPrintSettings();
    const tpl = getTemplate(printSettings.templateId);

    // Map invoice type → list/edit path prefix
    const TYPE_TO_PATH = {
        sale: "/sales", purchase: "/purchases", quotation: "/quotations",
        sale_order: "/sale-orders", proforma: "/proforma",
        credit_note: "/credit-notes", debit_note: "/debit-notes",
    };
    const editPath = `${TYPE_TO_PATH[inv.type] || "/sales"}/${id}/edit`;

    return (
        <div className="space-y-6 max-w-4xl mx-auto" data-testid="invoice-view-page">
            <div className="flex flex-wrap items-center justify-between gap-2 print:hidden">
                <Button variant="ghost" size="sm" onClick={() => navigate(-1)} data-testid="invoice-back-button"><ArrowLeft className="h-4 w-4 mr-1.5" /> Back</Button>
                <div className="flex flex-wrap gap-2">
                    <Button size="sm" variant="outline" onClick={shareWhatsApp} data-testid="invoice-whatsapp-button" className="border-emerald-500/50 text-emerald-700 dark:text-emerald-400 hover:bg-emerald-500/10">
                        <MessageCircle className="h-4 w-4 mr-1.5" /> {t("common.share")}
                    </Button>
                    <Button
                        size="sm"
                        variant="outline"
                        onClick={openSharePanel}
                        data-testid="invoice-share-panel-button"
                        className="border-indigo-500/50 text-indigo-700 dark:text-indigo-400 hover:bg-indigo-500/10"
                    >
                        <Share2 className="h-4 w-4 mr-1.5" /> Share…
                    </Button>
                    {twilio?.configured && (
                        <>
                            <Button size="sm" variant="outline" onClick={() => openSend("whatsapp")} data-testid="invoice-send-whatsapp">
                                <Send className="h-4 w-4 mr-1.5" /> {t("common.sendWhatsApp")}
                            </Button>
                            <Button size="sm" variant="outline" onClick={() => openSend("sms")} data-testid="invoice-send-sms">
                                <Send className="h-4 w-4 mr-1.5" /> {t("common.sendSMS")}
                            </Button>
                        </>
                    )}
                    <Button size="sm" variant="outline" onClick={() => downloadJson("einvoice")} data-testid="invoice-einvoice-button">
                        <FileJson className="h-4 w-4 mr-1.5" /> {t("inv.downloadEinvoice")}
                    </Button>
                    <Button size="sm" variant="outline" onClick={() => downloadJson("eway")} data-testid="invoice-eway-button">
                        <Truck className="h-4 w-4 mr-1.5" /> {t("inv.downloadEway")}
                    </Button>
                    <Button size="sm" variant="outline" onClick={() => downloadInvoicePDF(inv, active || {})} data-testid="invoice-pdf-button">
                        <FileDown className="h-4 w-4 mr-1.5" /> PDF
                    </Button>
                    <Button size="sm" variant="outline" onClick={() => thermalPrint(inv, active || {})} data-testid="invoice-thermal-button">
                        <Receipt className="h-4 w-4 mr-1.5" /> Thermal 80mm
                    </Button>
                    <Button
                        size="sm"
                        variant="outline"
                        onClick={() => navigate(editPath)}
                        disabled={inv.status === "cancelled"}
                        className="border-amber-500/50 text-amber-700 dark:text-amber-400 hover:bg-amber-500/10"
                        data-testid="invoice-edit-button"
                    >
                        <Pencil className="h-4 w-4 mr-1.5" /> Edit
                    </Button>
                    {party?.latitude && party?.longitude && (
                        <Button
                            size="sm"
                            variant="outline"
                            onClick={() => openInGoogleMaps(party.latitude, party.longitude, party.name)}
                            className="border-blue-500/50 text-blue-700 dark:text-blue-400 hover:bg-blue-500/10"
                            data-testid="invoice-open-maps-button"
                            title={`${party.latitude.toFixed(5)}, ${party.longitude.toFixed(5)}`}
                        >
                            <MapPin className="h-4 w-4 mr-1.5" /> Open in Maps
                        </Button>
                    )}
                    <Button onClick={() => window.print()} className="bg-primary hover:bg-primary/90" data-testid="invoice-print-button">
                        <Printer className="h-4 w-4 mr-1.5" /> {t("common.print")}
                    </Button>
                </div>
            </div>

            <Dialog open={sendOpen} onOpenChange={setSendOpen}>
                <DialogContent className="max-w-lg">
                    <DialogHeader><DialogTitle>{sendChannel === "whatsapp" ? "Send WhatsApp Message" : "Send SMS"}</DialogTitle></DialogHeader>
                    <div className="space-y-3">
                        <div className="space-y-1">
                            <Label className="text-[11px] uppercase tracking-wider font-semibold text-muted-foreground">Recipient Phone (with country code)</Label>
                            <Input value={sendTo} onChange={(e) => setSendTo(e.target.value)} placeholder="+919049202606" data-testid="send-to-input" />
                        </div>
                        <div className="space-y-1">
                            <Label className="text-[11px] uppercase tracking-wider font-semibold text-muted-foreground">Message</Label>
                            <textarea value={sendBody} onChange={(e) => setSendBody(e.target.value)} rows={6}
                                className="w-full rounded-md border border-border bg-background p-2 text-sm font-mono" data-testid="send-body-input" />
                        </div>
                    </div>
                    <DialogFooter>
                        <Button variant="outline" onClick={() => setSendOpen(false)}>Cancel</Button>
                        <Button onClick={doSend} disabled={!sendTo || sending} className="bg-primary hover:bg-primary/90" data-testid="send-confirm">
                            <Send className="h-4 w-4 mr-1.5" /> {sending ? "Sending…" : "Send"}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <SharePanel
                open={shareOpen}
                onOpenChange={setShareOpen}
                url={shareUrl || (typeof window !== "undefined" ? window.location.href : "")}
                title={`Invoice ${inv.invoice_no}`}
                message={shareMessage || `Namaste ${inv.party_name || "Customer"},\n\n${active?.name || "RGE Regalgoa"} se aapka invoice ${inv.invoice_no} ka link:\n${shareUrl}\n\nTotal: ₹${Number(inv.total || 0).toFixed(2)}\nBalance: ₹${Math.max(0, (inv.total || 0) - (inv.payment_received || 0)).toFixed(2)}\n\nDhanyavaad!`}
                phone={party?.phone || ""}
                email={party?.email || ""}
                fileName={`${(inv.invoice_no || "invoice").replace(/\//g, "-")}.pdf`}
            />

            <Card className="border-2 print-invoice" style={{ "--acc": tpl.accent, "--accSoft": tpl.accentSoft }}><CardContent className="p-0 print:p-0">
                {/* Themed banner header */}
                {tpl.headerStyle === "filled" && (
                    <div className="h-2.5" style={{ background: tpl.accent }} />
                )}
                {tpl.headerStyle === "banded" && (<>
                    <div className="h-2" style={{ background: tpl.accent }} />
                    <div className="h-1" style={{ background: tpl.accentSoft }} />
                </>)}
                <div className="p-8 print:p-6">
                <div className="flex items-start justify-between border-b border-border pb-5 gap-4">
                    <div className="flex items-start gap-4">
                        {printSettings.showLogo && <img src={printSettings.logoImage || "/logo.png"} alt="" className="h-16 w-16 rounded-full ring-2 ring-amber-400/50 print:ring-0 shrink-0 object-contain bg-white" />}
                        <div>
                            <div className="font-display text-2xl font-bold tracking-tight" style={{ color: tpl.accent }}>{active?.name || "Company"}</div>
                            {printSettings.tagline && <div className="text-xs italic mt-0.5" style={{ color: tpl.accentSoft }}>{printSettings.tagline}</div>}
                            <div className="text-xs text-muted-foreground mt-1 max-w-md">{active?.address}</div>
                            <div className="text-xs mt-1 font-mono">
                                {active?.gstin && <>GSTIN: {active.gstin}</>}
                                {active?.phone && <> · {active.phone}</>}
                            </div>
                            {active?.email && <div className="text-xs font-mono text-muted-foreground">{active.email}</div>}
                        </div>
                    </div>
                    <div className="text-right">
                        <div className="label-cap" style={{ color: tpl.accent }}>{inv.type === "quotation" ? "Quotation" : inv.type === "purchase" ? "Purchase Bill" : "Tax Invoice"}</div>
                        <div className="font-display text-xl font-bold mt-1 num">{inv.invoice_no}</div>
                        <div className="text-xs text-muted-foreground mt-1">{formatDate(inv.invoice_date)}</div>
                        {inv.copy_type && <div className="text-[10px] text-muted-foreground mt-0.5">({inv.copy_type})</div>}
                        <Badge className="mt-2 capitalize">{inv.status}</Badge>
                    </div>
                </div>

                <div className="grid grid-cols-2 gap-6 py-5 border-b border-border">
                    <div>
                        <div className="label-cap">Bill To</div>
                        <div className="font-semibold mt-1">{inv.party_name || "Walk-in Customer"}</div>
                        {inv.party_gstin && <div className="text-xs font-mono text-muted-foreground mt-0.5">GSTIN: {inv.party_gstin}</div>}
                        {inv.party_state && <div className="text-xs text-muted-foreground">State: {inv.party_state}</div>}
                    </div>
                    <div className="text-right">
                        <div className="label-cap">Payment Mode</div>
                        <div className="text-sm mt-1">{inv.payment_mode || "—"}</div>
                        {inv.interstate && <Badge variant="outline" className="mt-2 text-[10px] border-amber-500 text-amber-700 dark:text-amber-400">Inter-state · IGST</Badge>}
                    </div>
                </div>

                <table className="w-full text-sm dense-table mt-2">
                    <thead className="border-b" style={{ borderColor: tpl.accent }}>
                        <tr className="text-left text-[10px] tracking-wider uppercase" style={{ color: tpl.accent }}>
                            <th className="py-2">#</th>
                            <th>Item</th>
                            <th>HSN</th>
                            <th className="text-right">Qty</th>
                            <th className="text-right">Rate</th>
                            <th className="text-right">Disc%</th>
                            <th className="text-right">GST%</th>
                            <th className="text-right">Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        {(inv.lines || []).map((ln, i) => (
                            <tr key={`${ln.item_id || ln.name || "line"}-${i}`} className="border-b border-border/40">
                                <td className="py-2">{i + 1}</td>
                                <td>{ln.name}</td>
                                <td className="font-mono text-xs">{ln.hsn || "—"}</td>
                                <td className="text-right num">{ln.qty} {ln.unit}</td>
                                <td className="text-right num">{formatINR(ln.rate)}</td>
                                <td className="text-right num">{ln.discount || 0}%</td>
                                <td className="text-right num">{ln.gst_rate}%</td>
                                <td className="text-right num font-medium">{formatINR(ln.total)}</td>
                            </tr>
                        ))}
                    </tbody>
                </table>

                <div className="grid grid-cols-2 gap-6 pt-5">
                    <div className="space-y-3">
                        <div>
                            <div className="label-cap">{t("inv.amountInWords")}</div>
                            <div className="text-xs mt-1 font-medium italic">{amountInWords(inv.total)}</div>
                        </div>
                        {inv.notes && (
                            <div>
                                <div className="label-cap">Notes / Terms</div>
                                <div className="text-xs text-muted-foreground mt-1 whitespace-pre-wrap">{inv.notes}</div>
                            </div>
                        )}
                    </div>
                    <div className="space-y-1.5 text-sm">
                        <Row label="Subtotal" value={formatINR(inv.subtotal)} />
                        {inv.interstate ? (
                            <Row label="IGST" value={formatINR(inv.igst)} muted />
                        ) : (
                            <>
                                <Row label="CGST" value={formatINR(inv.cgst)} muted />
                                <Row label="SGST" value={formatINR(inv.sgst)} muted />
                            </>
                        )}
                        {inv.extra_discount > 0 && <Row label="Discount" value={`- ${formatINR(inv.extra_discount)}`} muted />}
                        {inv.round_off !== 0 && inv.round_off != null && <Row label="Round Off" value={formatINR(inv.round_off)} muted />}
                        <div className="flex items-center justify-between pt-2 border-t" style={{ borderColor: tpl.accent }}>
                            <span className="label-cap" style={{ color: tpl.accent }}>Grand Total</span>
                            <span className="font-display text-2xl font-bold num" style={{ color: tpl.accent }}>{formatINR(inv.total)}</span>
                        </div>
                        <Row label="Paid" value={formatINR(inv.payment_received)} />
                        <Row label="Balance" value={formatINR(Math.max(0, inv.total - inv.payment_received))} bold />
                    </div>
                </div>

                <div className="mt-8 pt-5 border-t border-border grid grid-cols-2 gap-6 text-[11px] text-muted-foreground">
                    <div>
                        <div className="font-semibold mb-1" style={{ color: tpl.accent }}>Terms & Conditions</div>
                        <div className="whitespace-pre-wrap leading-relaxed">{inv.terms_text || printSettings.defaultTerms}</div>
                        {/* Secure UPI QR — auto-resolved per `sales` module mapping (independent of printSettings) */}
                        <div className="mt-3 pt-2 border-t border-dashed border-border" data-testid="invoice-secure-upi-qr">
                            <div className="font-semibold mb-1" style={{ color: tpl.accent }}>Pay via UPI</div>
                            <SecureUpiQR
                                module="sales"
                                amount={inv.total}
                                note={`Inv ${inv.invoice_no || ""}`.trim()}
                                size={120}
                                compact
                            />
                        </div>
                        {(printSettings.showBankDetails || (printSettings.showQrUpi && printSettings.upiId)) && (
                            <div className="mt-3 pt-2 border-t border-dashed border-border">
                                <div className="font-semibold mb-1" style={{ color: tpl.accent }}>Bank Details</div>
                                {printSettings.showBankDetails && (
                                    <div className="font-mono text-[10px] leading-snug">
                                        {printSettings.bankName && <div>Bank: {printSettings.bankName}</div>}
                                        {printSettings.bankAccount && <div>A/C: {printSettings.bankAccount}</div>}
                                        {printSettings.bankIfsc && <div>IFSC: {printSettings.bankIfsc}</div>}
                                        {printSettings.bankBranch && <div>Branch: {printSettings.bankBranch}</div>}
                                    </div>
                                )}
                                {printSettings.showQrUpi && printSettings.upiId && (
                                    <div className="font-mono text-[10px] mt-1">UPI: {printSettings.upiId}</div>
                                )}
                            </div>
                        )}
                    </div>
                    {printSettings.showSignature && (
                        <div className="text-right">
                            <div className="font-semibold mb-1">For {active?.name || "Company"}</div>
                            {printSettings.signatureImage && (
                                <img src={printSettings.signatureImage} alt="signature" className="h-12 ml-auto my-2 object-contain" />
                            )}
                            <div className="mt-6 pt-2 border-t border-border inline-block px-6">{printSettings.signatureName}</div>
                        </div>
                    )}
                </div>

                <div className="mt-5 pt-3 border-t border-border text-[10px] text-muted-foreground flex items-center justify-between">
                    <div>{printSettings.footerNote || "Generated by RGE Regalgoa ERP AI · A new beginning of prosperity in business."} · {formatDate(inv.created_at)}</div>
                    <div>This is a computer generated document.</div>
                </div>
                </div>
            </CardContent></Card>

            <style>{`
                @media print {
                    aside, header, .print\\:hidden { display: none !important; }
                    main { padding: 0 !important; }
                    body { background: #fff !important; color: #000 !important; }
                    .print-invoice { border: none !important; box-shadow: none !important; }
                }
                /* 80mm thermal printer */
                @media print and (max-width: 80mm) {
                    .print-invoice { width: 80mm !important; max-width: 80mm !important; }
                    .print-invoice * { font-size: 10px !important; }
                }
            `}</style>
        </div>
    );
}

function Row({ label, value, muted, bold }) {
    return (
        <div className="flex items-center justify-between">
            <span className={`text-xs ${muted ? "text-muted-foreground" : ""}`}>{label}</span>
            <span className={`num ${bold ? "font-bold" : "font-medium"}`}>{value}</span>
        </div>
    );
}
