'use client';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
import { Label } from '@/components/ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { useTranslation } from '@/hooks/use-translation';
import { cn } from '@/lib/utils';
import type { ChartType, RevenueSeriesName } from '@/types/revenu';
import { Settings2 } from 'lucide-react';
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Line, LineChart, XAxis } from 'recharts';

export interface ChartPoint {
    label: string;
    value: number;
    comparison?: number;
}

/**
 * Carte de graphique configurable : métrique et type choisis par l'utilisateur.
 *
 * Le serveur envoie déjà les dix séries à chaque requête — choisir laquelle
 * s'affiche ne coûte donc aucun aller-retour. La configuration voyage dans
 * l'URL avec les filtres : un tableau de bord arrangé reste un lien partageable.
 */
export function ChartCard({
    metric,
    type,
    metricOptions,
    onMetricChange,
    onTypeChange,
    data,
    unit,
    description,
    dateFrom,
    dateTo,
    comparisonLabel,
}: {
    metric: RevenueSeriesName;
    type: ChartType;
    metricOptions: { id: RevenueSeriesName; name: string }[];
    onMetricChange: (next: RevenueSeriesName) => void;
    onTypeChange: (next: ChartType) => void;
    data: ChartPoint[];
    unit: string;
    description: string;
    dateFrom: string;
    dateTo: string;
    comparisonLabel: string;
}) {
    const { t } = useTranslation();
    const hasComparison = data.some((point) => point.comparison !== undefined);
    const title = metricOptions.find((option) => option.id === metric)?.name ?? metric;

    const chartConfig = {
        value: { label: `${dateFrom} – ${dateTo}`, color: 'var(--chart-1)' },
        comparison: { label: comparisonLabel || t('revenu', 'comparison_line'), color: 'var(--destructive)' },
    } satisfies ChartConfig;

    const tickInterval = data.length > 24 ? Math.ceil(data.length / 12) - 1 : 0;
    const formatValue = (value: unknown) => `${Math.round(Number(value)).toLocaleString('fr-FR')} ${unit}`;

    /**
     * Chaque ligne de l'infobulle dit À QUELLE PÉRIODE elle appartient.
     *
     * `ChartTooltipContent` remplace tout son rendu par le retour du formatter :
     * en ne renvoyant que le montant, on obtenait deux nombres nus empilés, sans
     * moyen de savoir lequel était la période comparée.
     */
    const tooltipRow = (value: unknown, name: unknown) => {
        const isComparison = name === 'comparison';

        return (
            <div className="flex w-full items-center justify-between gap-4">
                <span className="text-muted-foreground flex items-center gap-1.5">
                    <span
                        className="size-2.5 shrink-0 rounded-[2px]"
                        style={{ backgroundColor: isComparison ? 'var(--destructive)' : 'var(--color-secondary)' }}
                    />
                    {isComparison ? comparisonLabel || t('revenu', 'comparison_line') : `${dateFrom} – ${dateTo}`}
                </span>
                <span className="text-foreground font-medium tabular-nums">{formatValue(value)}</span>
            </div>
        );
    };

    const types: { id: ChartType; label: string }[] = [
        { id: 'line', label: t('revenu', 'chart_line') },
        { id: 'bar', label: t('revenu', 'chart_bar') },
        { id: 'area', label: t('revenu', 'chart_area') },
    ];

    // Grille, axe, infobulle et légende sont répétés dans chaque branche plutôt
    // que factorisés dans un fragment : recharts n'inspecte que ses enfants
    // DIRECTS pour les reconnaître. Enveloppés dans un <>…</>, ils lui deviennent
    // invisibles — ni axe, ni grille, ni infobulle au survol, ni légende.
    const grid = <CartesianGrid vertical={false} strokeDasharray="3 3" />;
    const xAxis = <XAxis dataKey="label" tickLine={false} axisLine={false} tickMargin={8} interval={tickInterval} minTickGap={8} />;
    const tooltip = <ChartTooltip cursor={false} content={<ChartTooltipContent formatter={tooltipRow} />} />;
    const legend = <ChartLegend content={<ChartLegendContent />} />;

    return (
        <Card>
            <CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0">
                <div className="grid gap-1">
                    <CardTitle>{title}</CardTitle>
                    <CardDescription>
                        {dateFrom} - {dateTo}
                    </CardDescription>
                </div>

                <Popover>
                    <PopoverTrigger asChild>
                        <Button variant="ghost" size="icon" className="size-8 shrink-0" aria-label={t('revenu', 'configure_chart')}>
                            <Settings2 className="size-4" />
                        </Button>
                    </PopoverTrigger>
                    <PopoverContent align="end" className="w-64 space-y-3">
                        <div className="space-y-1.5">
                            <Label className="text-muted-foreground text-xs">{t('revenu', 'chart_metric')}</Label>
                            <div className="grid gap-0.5">
                                {metricOptions.map((option) => (
                                    <button
                                        key={option.id}
                                        type="button"
                                        onClick={() => onMetricChange(option.id)}
                                        className={cn(
                                            'rounded-md px-2 py-1 text-left text-sm transition-colors',
                                            option.id === metric ? 'bg-muted font-medium' : 'hover:bg-muted',
                                        )}
                                    >
                                        {option.name}
                                    </button>
                                ))}
                            </div>
                        </div>

                        <div className="space-y-1.5 border-t pt-2">
                            <Label className="text-muted-foreground text-xs">{t('revenu', 'chart_type')}</Label>
                            <div className="flex gap-1">
                                {types.map((option) => (
                                    <Button
                                        key={option.id}
                                        variant={option.id === type ? 'default' : 'outline'}
                                        size="sm"
                                        className="h-7 flex-1 text-xs"
                                        onClick={() => onTypeChange(option.id)}
                                    >
                                        {option.label}
                                    </Button>
                                ))}
                            </div>
                        </div>
                    </PopoverContent>
                </Popover>
            </CardHeader>

            <CardContent>
                <ChartContainer config={chartConfig} className="aspect-auto h-[220px] w-full">
                    {type === 'bar' ? (
                        <BarChart accessibilityLayer data={data} margin={{ left: 28, right: 28 }}>
                            {grid}
                            {xAxis}
                            {tooltip}
                            {hasComparison && legend}
                            {hasComparison && <Bar dataKey="comparison" fill="var(--destructive)" fillOpacity={0.35} radius={4} />}
                            <Bar dataKey="value" fill="var(--color-secondary)" radius={4} />
                        </BarChart>
                    ) : type === 'area' ? (
                        <AreaChart accessibilityLayer data={data} margin={{ left: 28, right: 28 }}>
                            {grid}
                            {xAxis}
                            {tooltip}
                            {hasComparison && legend}
                            {hasComparison && (
                                <Area
                                    type="monotone"
                                    dataKey="comparison"
                                    stroke="var(--destructive)"
                                    strokeDasharray="5 4"
                                    fill="var(--destructive)"
                                    fillOpacity={0.08}
                                />
                            )}
                            <Area
                                type="monotone"
                                dataKey="value"
                                stroke="var(--color-secondary)"
                                fill="var(--color-secondary)"
                                fillOpacity={0.2}
                            />
                        </AreaChart>
                    ) : (
                        <LineChart accessibilityLayer data={data} margin={{ left: 28, right: 28 }}>
                            {grid}
                            {xAxis}
                            {tooltip}
                            {hasComparison && legend}
                            {hasComparison && (
                                <Line
                                    dataKey="comparison"
                                    type="natural"
                                    stroke="var(--destructive)"
                                    strokeWidth={2}
                                    strokeDasharray="5 4"
                                    dot={false}
                                />
                            )}
                            <Line dataKey="value" type="natural" stroke="var(--color-secondary)" strokeWidth={2} dot={false} />
                        </LineChart>
                    )}
                </ChartContainer>
            </CardContent>

            <CardFooter className="flex-col items-start gap-2 text-sm">
                <div className="text-muted-foreground leading-none">{description}</div>
            </CardFooter>
        </Card>
    );
}
