import { useState } from 'react';
import { router } from '@inertiajs/react';
import { FileSpreadsheet, FileText, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    captureDashboardCharts,
    downloadDashboardExport,
} from '@/lib/dashboard-chart-export';
import { toast } from 'sonner';
import {
    expenses,
    financial,
    payments,
    services,
} from '@/routes/admin/dashboards';
import {
    excel as exportExcel,
    pdf as exportPdf,
} from '@/routes/admin/dashboards/export';

export type DashboardFilters = {
    period: string;
    fiscal_year: number;
    month: number | null;
    quarter: number | null;
    service_id: number | null;
    user_id: number | null;
    label: string;
};

export type FilterOptions = {
    services: Array<{ id: number; code: string; name: string }>;
    collaborators: Array<{ id: number; name: string }>;
};

const TAB_ROUTES = {
    financial,
    services,
    expenses,
    payments,
} as const;

const MONTH_LABELS = [
    'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
    'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre',
];

export function DashboardFiltersBar({
    active,
    filters,
    filterOptions,
    showServiceFilter = false,
    showCollaboratorFilter = false,
}: {
    active: keyof typeof TAB_ROUTES;
    filters: DashboardFilters;
    filterOptions: FilterOptions;
    showServiceFilter?: boolean;
    showCollaboratorFilter?: boolean;
}) {
    function apply(next: Partial<DashboardFilters>) {
        const period = next.period ?? filters.period;
        const query: Record<string, string | number> = {
            period,
            fiscal_year: next.fiscal_year ?? filters.fiscal_year,
        };

        if (period === 'month') {
            query.month = next.month ?? filters.month ?? new Date().getMonth() + 1;
        }

        if (period === 'quarter') {
            query.quarter = next.quarter ?? filters.quarter ?? Math.ceil((new Date().getMonth() + 1) / 3);
        }

        if (showServiceFilter && (next.service_id ?? filters.service_id)) {
            query.service_id = next.service_id ?? filters.service_id ?? 0;
        }

        if (showCollaboratorFilter && (next.user_id ?? filters.user_id)) {
            query.user_id = next.user_id ?? filters.user_id ?? 0;
        }

        router.get(TAB_ROUTES[active].url({ query }), {}, { preserveState: true });
    }

    return (
        <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
            <div className="grid gap-1.5">
                <Label className="text-xs text-muted-foreground">Période</Label>
                <Select
                    value={filters.period}
                    onValueChange={(value) => apply({ period: value })}
                >
                    <SelectTrigger className="h-9 w-36">
                        <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem value="month">Mois</SelectItem>
                        <SelectItem value="quarter">Trimestre</SelectItem>
                        <SelectItem value="year">Année</SelectItem>
                    </SelectContent>
                </Select>
            </div>

            <div className="grid gap-1.5">
                <Label className="text-xs text-muted-foreground">Exercice</Label>
                <Input
                    type="number"
                    className="h-9 w-24"
                    value={filters.fiscal_year}
                    onChange={(e) =>
                        apply({ fiscal_year: Number(e.target.value) || filters.fiscal_year })
                    }
                />
            </div>

            {filters.period === 'month' && (
                <div className="grid gap-1.5">
                    <Label className="text-xs text-muted-foreground">Mois</Label>
                    <Select
                        value={String(filters.month ?? new Date().getMonth() + 1)}
                        onValueChange={(value) => apply({ month: Number(value) })}
                    >
                        <SelectTrigger className="h-9 w-36">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            {MONTH_LABELS.map((label, index) => (
                                <SelectItem key={label} value={String(index + 1)}>
                                    {label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
            )}

            {filters.period === 'quarter' && (
                <div className="grid gap-1.5">
                    <Label className="text-xs text-muted-foreground">Trimestre</Label>
                    <Select
                        value={String(filters.quarter ?? 1)}
                        onValueChange={(value) => apply({ quarter: Number(value) })}
                    >
                        <SelectTrigger className="h-9 w-28">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="1">T1</SelectItem>
                            <SelectItem value="2">T2</SelectItem>
                            <SelectItem value="3">T3</SelectItem>
                            <SelectItem value="4">T4</SelectItem>
                        </SelectContent>
                    </Select>
                </div>
            )}

            {showServiceFilter && (
                <div className="grid gap-1.5">
                    <Label className="text-xs text-muted-foreground">Prestation</Label>
                    <Select
                        value={filters.service_id ? String(filters.service_id) : 'all'}
                        onValueChange={(value) =>
                            apply({ service_id: value === 'all' ? null : Number(value) })
                        }
                    >
                        <SelectTrigger className="h-9 w-52">
                            <SelectValue placeholder="Toutes" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">Toutes les prestations</SelectItem>
                            {filterOptions.services.map((service) => (
                                <SelectItem key={service.id} value={String(service.id)}>
                                    {service.code} — {service.name}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
            )}

            {showCollaboratorFilter && (
                <div className="grid gap-1.5">
                    <Label className="text-xs text-muted-foreground">Collaborateur (NDF uniquement)</Label>
                    <Select
                        value={filters.user_id ? String(filters.user_id) : 'all'}
                        onValueChange={(value) =>
                            apply({ user_id: value === 'all' ? null : Number(value) })
                        }
                    >
                        <SelectTrigger className="h-9 w-52">
                            <SelectValue placeholder="Tous" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">Tous les collaborateurs</SelectItem>
                            {filterOptions.collaborators.map((user) => (
                                <SelectItem key={user.id} value={String(user.id)}>
                                    {user.name}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
            )}

            <p className="pb-2 text-sm text-muted-foreground sm:ml-auto">
                {filters.label}
            </p>
        </div>
    );
}

export function DashboardExportButtons({
    view,
    filters,
    canExport,
}: {
    view: 'financial' | 'services' | 'expenses' | 'payments';
    filters: DashboardFilters;
    canExport: boolean;
}) {
    const [exporting, setExporting] = useState<'excel' | 'pdf' | null>(null);

    if (!canExport) {
        return null;
    }

    const payload = {
        view,
        period: filters.period,
        fiscal_year: filters.fiscal_year,
        ...(filters.month ? { month: filters.month } : {}),
        ...(filters.quarter ? { quarter: filters.quarter } : {}),
        ...(filters.service_id ? { service_id: filters.service_id } : {}),
        ...(filters.user_id ? { user_id: filters.user_id } : {}),
    };

    async function handleExport(format: 'excel' | 'pdf') {
        setExporting(format);

        try {
            const charts = await captureDashboardCharts();
            const url =
                format === 'excel' ? exportExcel.url() : exportPdf.url();
            const accept =
                format === 'excel'
                    ? 'application/vnd.ms-excel'
                    : 'application/pdf';
            const extension = format === 'excel' ? 'xls' : 'pdf';

            await downloadDashboardExport(
                url,
                { ...payload, charts },
                accept,
                `tableau-de-bord-${view}-${new Date().toISOString().slice(0, 10)}.${extension}`,
            );
        } catch {
            toast.error('Impossible de générer l’export.');
        } finally {
            setExporting(null);
        }
    }

    return (
        <div className="flex flex-wrap gap-2">
            <Button
                variant="outline"
                disabled={exporting !== null}
                onClick={() => handleExport('excel')}
            >
                {exporting === 'excel' ? <Loader2 className="animate-spin" /> : <FileSpreadsheet />}
                Excel
            </Button>
            <Button
                variant="outline"
                disabled={exporting !== null}
                onClick={() => handleExport('pdf')}
            >
                {exporting === 'pdf' ? <Loader2 className="animate-spin" /> : <FileText />}
                PDF
            </Button>
        </div>
    );
}
