import { Badge } from '@/components/ui/badge';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { CalendarOff, TriangleAlert } from 'lucide-react';
import { useMemo } from 'react';
import { DEMAND_LEGEND, getPriceColor } from '../lib/price-color';
import type { PriceDay } from '../types';

interface PriceCalendarPreviewProps {
    /**
     * Les 90 jours calculés. Peut être vide (aucun aperçu encore reçu) ou absent
     * (appelant qui n'a rien à montrer) : ce composant ne doit JAMAIS être le
     * point de crash de l'écran.
     */
    preview: PriceDay[] | null | undefined;
    exchangeRate: number;
    basePrice: number;
    /**
     * `true` = la grille affichée est le DERNIER aperçu valide, pas le reflet de
     * la saisie en cours (celle-ci est refusée par le serveur). On la garde à
     * l'écran — l'utilisateur doit voir ce qu'il compare — mais on le dit.
     */
    stale?: boolean;
}

export default function PriceCalendarPreview({ preview, exchangeRate, basePrice, stale = false }: PriceCalendarPreviewProps) {
    // Une seule normalisation en tête : tout le reste du composant travaille sur
    // un tableau garanti. `preview.map(...)` sur un `undefined` — ce que rendait
    // un aperçu refusé en 422 — plantait auparavant tout le slide-over, sans
    // ErrorBoundary pour rattraper.
    const days = useMemo(() => (Array.isArray(preview) ? preview : []), [preview]);

    const stats = useMemo(() => {
        if (days.length === 0) {
            return { avg: 0, min: 0, max: 0, booked: 0, available: 0 };
        }
        const prices = days.map((d) => d.price);
        return {
            avg: Math.round(prices.reduce((a, b) => a + b, 0) / prices.length),
            min: Math.min(...prices),
            max: Math.max(...prices),
            booked: days.filter((d) => d.is_booked).length,
            available: days.filter((d) => !d.is_booked).length,
        };
    }, [days]);

    // Regroupement par mois
    const months = useMemo(() => {
        const grouped: Record<string, PriceDay[]> = {};
        for (const day of days) {
            const monthKey = day.date.substring(0, 7); // YYYY-MM
            if (!grouped[monthKey]) grouped[monthKey] = [];
            grouped[monthKey].push(day);
        }
        return grouped;
    }, [days]);

    function formatMonth(key: string): string {
        const [year, month] = key.split('-');
        const date = new Date(Number(year), Number(month) - 1);
        return date.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' });
    }

    // État vide EXPLICITE : aucun aperçu reçu (premier chargement, ou tout
    // premier calcul déjà refusé). Mieux vaut le dire que d'afficher une grille
    // de statistiques à zéro qui se lirait comme un vrai résultat.
    if (days.length === 0) {
        return (
            <div className="text-muted-foreground flex flex-col items-center gap-2 rounded-lg border border-dashed px-4 py-10 text-center text-sm">
                <CalendarOff className="h-6 w-6" />
                <p>Aucun aperçu à afficher pour l’instant.</p>
                <p className="text-xs">Corrigez la bande tarifaire (min ≤ base ≤ max, minimum &gt; 0) pour lancer le calcul.</p>
            </div>
        );
    }

    return (
        <div className="space-y-4">
            {stale && (
                <div className="flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-800 dark:border-amber-900/40 dark:bg-amber-950/30 dark:text-amber-200">
                    <TriangleAlert className="mt-0.5 h-3.5 w-3.5 shrink-0" />
                    <span>Aperçu figé : la saisie en cours est invalide, cette grille est le dernier calcul valide.</span>
                </div>
            )}

            {/* Statistiques */}
            <div className="grid grid-cols-5 gap-2 text-center text-xs">
                <div className="bg-muted rounded-md p-2">
                    <div className="text-muted-foreground">Moy.</div>
                    <div className="font-semibold">${stats.avg}</div>
                </div>
                <div className="bg-muted rounded-md p-2">
                    <div className="text-muted-foreground">Min</div>
                    <div className="font-semibold">${stats.min}</div>
                </div>
                <div className="bg-muted rounded-md p-2">
                    <div className="text-muted-foreground">Max</div>
                    <div className="font-semibold">${stats.max}</div>
                </div>
                <div className="bg-muted rounded-md p-2">
                    <div className="text-muted-foreground">Réservé</div>
                    <div className="font-semibold">{stats.booked}</div>
                </div>
                <div className="bg-muted rounded-md p-2">
                    <div className="text-muted-foreground">Dispo</div>
                    <div className="font-semibold">{stats.available}</div>
                </div>
            </div>

            {/* Calendrier, mois par mois */}
            <TooltipProvider>
                <div className="space-y-4">
                    {Object.entries(months).map(([monthKey, monthDays]) => (
                        <div key={monthKey}>
                            <h4 className="mb-2 text-sm font-medium capitalize">{formatMonth(monthKey)}</h4>
                            <div className="grid grid-cols-7 gap-1">
                                {/* En-têtes de jour */}
                                {['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'].map((d) => (
                                    <div key={d} className="text-muted-foreground text-center text-[10px] font-medium">
                                        {d}
                                    </div>
                                ))}
                                {/* Décalage du premier jour du mois */}
                                {(() => {
                                    const firstDate = new Date(monthDays[0].date);
                                    const dayOfWeek = (firstDate.getDay() + 6) % 7; // Lundi = 0
                                    return Array.from({ length: dayOfWeek }, (_, i) => <div key={`offset-${i}`} />);
                                })()}
                                {/* Jours */}
                                {monthDays.map((day) => {
                                    const dateObj = new Date(day.date);
                                    const dayNum = dateObj.getDate();

                                    return (
                                        <Tooltip key={day.date}>
                                            <TooltipTrigger asChild>
                                                <div
                                                    className={`relative flex cursor-default flex-col items-center justify-center rounded p-1 text-[10px] ${day.is_booked ? 'bg-muted/80 line-through opacity-50' : getPriceColor(day.price, basePrice)}`}
                                                >
                                                    <span className="font-medium">{dayNum}</span>
                                                    <span className="font-bold">${day.price}</span>
                                                </div>
                                            </TooltipTrigger>
                                            <TooltipContent side="top" className="max-w-[200px]">
                                                <div className="space-y-1 text-xs">
                                                    <div className="font-medium">
                                                        {dateObj.toLocaleDateString('fr-FR', { weekday: 'long', day: 'numeric', month: 'long' })}
                                                    </div>
                                                    <div>
                                                        ${day.price} USD ({Math.round(day.price * exchangeRate)} TND)
                                                    </div>
                                                    {day.is_booked && (
                                                        <Badge variant="secondary" className="text-[10px]">
                                                            Réservé
                                                        </Badge>
                                                    )}
                                                    {Array.isArray(day.reason) && day.reason.length > 0 && (
                                                        <ul className="text-muted-foreground">
                                                            {day.reason.map((r, i) => (
                                                                <li key={i}>• {r}</li>
                                                            ))}
                                                        </ul>
                                                    )}
                                                </div>
                                            </TooltipContent>
                                        </Tooltip>
                                    );
                                })}
                            </div>
                        </div>
                    ))}
                </div>
            </TooltipProvider>

            {/* Légende */}
            <div className="flex flex-wrap gap-2 text-[10px]">
                {DEMAND_LEGEND.map((item) => (
                    <span key={item.label} className="flex items-center gap-1">
                        <span className={`h-3 w-3 rounded border ${item.className}`} />
                        {item.label}
                    </span>
                ))}
            </div>
        </div>
    );
}
