import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { BarChart2, Download, FileSpreadsheet, FileText, Image, Table2 } from 'lucide-react';
import { useState } from 'react';

declare const route: (...args: any[]) => string;

// ─── Types ────────────────────────────────────────────────────────────────────

interface ColumnDef {
    key: string;
    label: string;
    sortable: boolean;
    type: string;
}

interface FilterValues {
    [key: string]: any;
}

interface Props {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    reportLabel: string;
    columns: ColumnDef[];
    filterValues: FilterValues;
    currentModule: string;
    exportDataRoute: string;
    exportGraphRoute: string;
    hasRun: boolean;
}

type ExportPath = 'data' | 'graph';

const GRAPH_SECTIONS = [
    { id: 'summary',       label: 'Summary Cards',    desc: '4 top-level KPI cards',         domId: 'export-section-summary' },
    { id: 'sub_summary',   label: 'KPI Metrics',      desc: 'Secondary KPI strip',            domId: 'export-section-sub-summary' },
    { id: 'primary_chart', label: 'Primary Chart',    desc: 'Main trend chart',               domId: 'export-section-primary-chart' },
    { id: 'aux_charts',    label: 'Analytics Charts', desc: 'Dual chart analytics panel',     domId: 'export-section-aux-charts' },
];

// ─── SVG → PNG capture ───────────────────────────────────────────────────────
// DomPDF cannot reliably render complex SVG paths (bezier curves from Recharts).
// We convert each SVG to a PNG via canvas before sending to the server.

async function captureSvgsFromSection(domId: string): Promise<string[]> {
    const container = document.getElementById(domId);
    if (!container) return [];
    const svgs = Array.from(container.querySelectorAll('svg'));
    const results: string[] = [];

    for (const svg of svgs) {
        try {
            const bbox  = svg.getBoundingClientRect();
            const w     = Math.round(bbox.width  || 600);
            const h     = Math.round(bbox.height || 260);
            const scale = 2; // retina quality

            // Clone and fix dimensions for serialization
            const clone = svg.cloneNode(true) as SVGElement;
            clone.setAttribute('width',  String(w));
            clone.setAttribute('height', String(h));
            clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');

            const svgStr  = new XMLSerializer().serializeToString(clone);
            const svgBlob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
            const svgUrl  = URL.createObjectURL(svgBlob);

            // Draw SVG → canvas → PNG
            const b64 = await new Promise<string>((resolve, reject) => {
                const img    = new Image();
                img.onload = () => {
                    const canvas  = document.createElement('canvas');
                    canvas.width  = w * scale;
                    canvas.height = h * scale;
                    const ctx = canvas.getContext('2d')!;
                    ctx.fillStyle = '#ffffff';
                    ctx.fillRect(0, 0, canvas.width, canvas.height);
                    ctx.scale(scale, scale);
                    ctx.drawImage(img, 0, 0, w, h);
                    URL.revokeObjectURL(svgUrl);
                    // Strip the "data:image/png;base64," prefix
                    resolve(canvas.toDataURL('image/png').split(',')[1]);
                };
                img.onerror = () => { URL.revokeObjectURL(svgUrl); reject(new Error('img load failed')); };
                img.src = svgUrl;
            });

            if (b64) results.push(b64);
        } catch {
            // skip charts that fail to capture
        }
    }

    return results;
}

// ─── Component ────────────────────────────────────────────────────────────────

export default function ReportExportModal({
    open,
    onOpenChange,
    reportLabel,
    columns,
    filterValues,
    currentModule,
    exportDataRoute,
    exportGraphRoute,
    hasRun,
}: Props) {
    const [exportPath, setExportPath]           = useState<ExportPath>('data');
    const [dataFormat, setDataFormat]           = useState<'csv' | 'pdf'>('csv');
    const [selectedCols, setSelectedCols]       = useState<string[]>(() => columns.map((c) => c.key));
    const [selectedSections, setSelectedSections] = useState<string[]>(GRAPH_SECTIONS.map((s) => s.id));
    const [loading, setLoading]                 = useState(false);

    const allColsSelected = selectedCols.length === columns.length;

    const toggleCol = (key: string, checked: boolean) => {
        setSelectedCols((prev) => checked ? [...prev, key] : prev.filter((k) => k !== key));
    };

    const toggleSection = (id: string, checked: boolean) => {
        setSelectedSections((prev) => checked ? [...prev, id] : prev.filter((s) => s !== id));
    };

    const toggleAllCols = () => {
        setSelectedCols(allColsSelected ? [] : columns.map((c) => c.key));
    };

    // ── Data export via form POST (triggers browser download) ─────────────────

    const submitDataExport = () => {
        const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ?? '';
        const form = document.createElement('form');
        form.method = 'POST';
        form.action = exportDataRoute;
        form.style.display = 'none';

        const addHidden = (name: string, val: string) => {
            const el = document.createElement('input');
            el.name  = name;
            el.value = val;
            form.appendChild(el);
        };

        addHidden('_token',  csrf);
        addHidden('module',  currentModule);
        addHidden('format',  dataFormat);

        // Filter values
        Object.entries(filterValues).forEach(([k, v]) => {
            if (Array.isArray(v)) {
                v.forEach((item) => { if (item !== '' && item != null) addHidden(`${k}[]`, String(item)); });
            } else if (v !== '' && v != null) {
                addHidden(k, String(v));
            }
        });

        // Selected columns
        selectedCols.forEach((col) => addHidden('columns[]', col));

        document.body.appendChild(form);
        form.submit();
        document.body.removeChild(form);
        onOpenChange(false);
    };

    // ── Graph export — capture SVGs → POST JSON → blob download ──────────────

    const submitGraphExport = async () => {
        setLoading(true);
        try {
            // Capture each section's charts as PNG (async, canvas-based)
            const svgData: Record<string, string[]> = {};
            await Promise.all(
                selectedSections.map(async (sectionId) => {
                    const sec = GRAPH_SECTIONS.find((s) => s.id === sectionId);
                    if (sec) {
                        const captured = await captureSvgsFromSection(sec.domId);
                        if (captured.length) svgData[sectionId] = captured;
                    }
                }),
            );

            const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ?? '';
            const response = await fetch(exportGraphRoute, {
                method: 'POST',
                headers: {
                    'Content-Type':    'application/json',
                    'X-CSRF-TOKEN':    csrf,
                    'X-Requested-With': 'XMLHttpRequest',
                },
                body: JSON.stringify({
                    module:   currentModule,
                    sections: selectedSections,
                    svg_data: svgData,
                    ...Object.fromEntries(
                        Object.entries(filterValues).filter(([, v]) => v !== '' && v != null),
                    ),
                }),
            });

            if (!response.ok) throw new Error(`Export failed: ${response.status}`);

            const blob = await response.blob();
            const url  = URL.createObjectURL(blob);
            const a    = document.createElement('a');
            a.href     = url;
            a.download = `${currentModule}-graph-report.pdf`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            onOpenChange(false);
        } catch (err) {
            console.error(err);
            alert('Graph export failed. Please try again.');
        } finally {
            setLoading(false);
        }
    };

    const handleExport = () => {
        if (exportPath === 'data') submitDataExport();
        else submitGraphExport();
    };

    const canExport = exportPath === 'data'
        ? selectedCols.length > 0
        : selectedSections.length > 0;

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-lg">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2 text-base font-semibold">
                        <Download className="h-4 w-4 text-[#008060]" />
                        Export {reportLabel} Report
                    </DialogTitle>
                </DialogHeader>

                <div className="space-y-5 py-1">

                    {/* ── Step 1: Export type ──────────────────────────────── */}
                    <div>
                        <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-[#6d7175]">
                            Export Type
                        </p>
                        <div className="grid grid-cols-2 gap-3">
                            {/* Data card */}
                            <button
                                type="button"
                                onClick={() => setExportPath('data')}
                                className={`flex items-start gap-3 rounded-xl border p-3 text-left transition-colors ${
                                    exportPath === 'data'
                                        ? 'border-[#008060] bg-[#f0faf6] shadow-sm'
                                        : 'border-[#d8d8d8] bg-white hover:bg-[#f6f6f7]'
                                }`}
                            >
                                <div className={`mt-0.5 rounded-lg p-1.5 ${exportPath === 'data' ? 'bg-[#008060]/10' : 'bg-gray-100'}`}>
                                    <Table2 className={`h-4 w-4 ${exportPath === 'data' ? 'text-[#008060]' : 'text-gray-500'}`} />
                                </div>
                                <div>
                                    <p className={`text-sm font-semibold ${exportPath === 'data' ? 'text-[#008060]' : 'text-[#202223]'}`}>
                                        Data Export
                                    </p>
                                    <p className="text-xs text-[#6d7175]">Table rows as CSV or PDF</p>
                                </div>
                            </button>

                            {/* Graph card */}
                            <button
                                type="button"
                                onClick={() => setExportPath('graph')}
                                disabled={!hasRun}
                                className={`flex items-start gap-3 rounded-xl border p-3 text-left transition-colors ${
                                    exportPath === 'graph'
                                        ? 'border-[#008060] bg-[#f0faf6] shadow-sm'
                                        : 'border-[#d8d8d8] bg-white hover:bg-[#f6f6f7]'
                                } disabled:cursor-not-allowed disabled:opacity-50`}
                            >
                                <div className={`mt-0.5 rounded-lg p-1.5 ${exportPath === 'graph' ? 'bg-[#008060]/10' : 'bg-gray-100'}`}>
                                    <BarChart2 className={`h-4 w-4 ${exportPath === 'graph' ? 'text-[#008060]' : 'text-gray-500'}`} />
                                </div>
                                <div>
                                    <p className={`text-sm font-semibold ${exportPath === 'graph' ? 'text-[#008060]' : 'text-[#202223]'}`}>
                                        Graph Export
                                    </p>
                                    <p className="text-xs text-[#6d7175]">Charts &amp; KPIs as PDF</p>
                                </div>
                            </button>
                        </div>
                    </div>

                    {/* ── Step 2a: Data options ─────────────────────────────── */}
                    {exportPath === 'data' && (
                        <div className="space-y-4">
                            {/* Format */}
                            <div>
                                <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-[#6d7175]">
                                    Format
                                </p>
                                <RadioGroup
                                    value={dataFormat}
                                    onValueChange={(v) => setDataFormat(v as 'csv' | 'pdf')}
                                    className="flex gap-4"
                                >
                                    <label className="flex cursor-pointer items-center gap-2">
                                        <RadioGroupItem value="csv" id="fmt-csv" />
                                        <span className="flex items-center gap-1.5 text-sm font-medium">
                                            <FileSpreadsheet className="h-3.5 w-3.5 text-green-600" />
                                            CSV
                                        </span>
                                    </label>
                                    <label className="flex cursor-pointer items-center gap-2">
                                        <RadioGroupItem value="pdf" id="fmt-pdf" />
                                        <span className="flex items-center gap-1.5 text-sm font-medium">
                                            <FileText className="h-3.5 w-3.5 text-red-500" />
                                            PDF
                                        </span>
                                    </label>
                                </RadioGroup>
                            </div>

                            {/* Columns */}
                            <div>
                                <div className="mb-2 flex items-center justify-between">
                                    <p className="text-xs font-semibold uppercase tracking-wide text-[#6d7175]">
                                        Fields to Include
                                    </p>
                                    <button
                                        type="button"
                                        onClick={toggleAllCols}
                                        className="text-xs font-medium text-[#008060] hover:underline"
                                    >
                                        {allColsSelected ? 'Deselect All' : 'Select All'}
                                    </button>
                                </div>
                                <div className="grid grid-cols-2 gap-2">
                                    {columns.map((col) => (
                                        <label
                                            key={col.key}
                                            className="flex cursor-pointer items-center gap-2 rounded-lg border border-[#e3e3e3] bg-[#fafafa] px-3 py-2 hover:bg-[#f0faf6]"
                                        >
                                            <Checkbox
                                                id={`col-${col.key}`}
                                                checked={selectedCols.includes(col.key)}
                                                onCheckedChange={(c) => toggleCol(col.key, !!c)}
                                            />
                                            <span className="text-xs font-medium text-[#202223]">{col.label}</span>
                                        </label>
                                    ))}
                                </div>
                            </div>
                        </div>
                    )}

                    {/* ── Step 2b: Graph options ────────────────────────────── */}
                    {exportPath === 'graph' && (
                        <div>
                            <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-[#6d7175]">
                                Sections to Include
                            </p>
                            <div className="space-y-2">
                                {GRAPH_SECTIONS.map((sec) => (
                                    <label
                                        key={sec.id}
                                        className="flex cursor-pointer items-center gap-3 rounded-lg border border-[#e3e3e3] bg-[#fafafa] px-3 py-2.5 hover:bg-[#f0faf6]"
                                    >
                                        <Checkbox
                                            id={`sec-${sec.id}`}
                                            checked={selectedSections.includes(sec.id)}
                                            onCheckedChange={(c) => toggleSection(sec.id, !!c)}
                                        />
                                        <Image className="h-3.5 w-3.5 shrink-0 text-[#6d7175]" />
                                        <div className="min-w-0">
                                            <p className="text-xs font-semibold text-[#202223]">{sec.label}</p>
                                            <p className="text-xs text-[#6d7175]">{sec.desc}</p>
                                        </div>
                                    </label>
                                ))}
                            </div>
                            <p className="mt-2 text-xs text-[#6d7175]">
                                Charts are captured from the current page view.
                            </p>
                        </div>
                    )}
                </div>

                <DialogFooter>
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onOpenChange(false)}
                        disabled={loading}
                        className="border-[#d8d8d8]"
                    >
                        Cancel
                    </Button>
                    <Button
                        size="sm"
                        onClick={handleExport}
                        disabled={!canExport || loading}
                        className="bg-[#008060] text-white hover:bg-[#006b51]"
                    >
                        {loading ? 'Exporting…' : (
                            <span className="flex items-center gap-1.5">
                                <Download className="h-3.5 w-3.5" />
                                Export
                            </span>
                        )}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}
