import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Slider } from '@/components/ui/slider';
import { useState } from 'react';
import type { PriceBandField } from '../lib/api-errors';
import HelpHint from './HelpHint';

interface PriceSlidersProps {
    minPrice: number;
    basePrice: number;
    maxPrice: number;
    exchangeRate: number;
    onChange: (field: PriceBandField, value: number) => void;
    /** Lecture seule (sans `yield.manage`) : les trois champs sont éteints. */
    disabled?: boolean;
    /** Le POURQUOI de l'extinction, affiché en infobulle sur chaque champ. */
    disabledReason?: string;
    /** Messages de validation renvoyés par le serveur, affichés sous le champ fautif. */
    errors?: Partial<Record<PriceBandField, string>>;
}

interface PriceFieldProps {
    id: string;
    label: string;
    help: string;
    field: PriceBandField;
    value: number;
    exchangeRate: number;
    onChange: (field: PriceBandField, value: number) => void;
    disabled: boolean;
    disabledReason?: string;
    error?: string;
}

/**
 * Un des trois curseurs de la bande tarifaire.
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * POURQUOI UN BROUILLON LOCAL
 * ═══════════════════════════════════════════════════════════════════════════
 * Le champ postait auparavant `Number(e.target.value)` directement. Or
 * `Number('') === 0` : vider « Prix minimum » — un geste de saisie banal, on
 * efface pour retaper — posait min_price à 0, valeur que le serveur refuse
 * (`gt:0`, sinon on publierait des nuits gratuites sur Airbnb / Booking), et
 * l'aperçu partait en 422 800 ms plus tard.
 *
 * Le brouillon garde le champ VISUELLEMENT vide pendant la frappe sans
 * propager de valeur : la bande reste sur son dernier nombre valide, l'aperçu
 * ne bouge pas. Au blur, l'affichage revient à la valeur réellement retenue.
 */
function PriceField({ id, label, help, field, value, exchangeRate, onChange, disabled, disabledReason, error }: PriceFieldProps) {
    const [draft, setDraft] = useState<string | null>(null);
    const texte = draft ?? String(value);
    const title = disabled ? disabledReason : undefined;

    return (
        <div className="space-y-3">
            <div className="flex items-center justify-between">
                <Label htmlFor={id} className="text-sm font-medium">
                    {label}
                    <HelpHint text={help} />
                </Label>
                <div className="flex items-center gap-2">
                    <Input
                        id={id}
                        type="number"
                        min={0}
                        value={texte}
                        disabled={disabled}
                        title={title}
                        aria-invalid={error ? true : undefined}
                        onChange={(e) => {
                            const brut = e.target.value;
                            setDraft(brut);
                            const nombre = Number(brut);
                            // Un champ vide (ou en cours de frappe : « - », « 1e ») ne
                            // remplace PAS la valeur retenue par un 0 fantôme.
                            if (brut.trim() !== '' && !Number.isNaN(nombre)) {
                                onChange(field, nombre);
                            }
                        }}
                        onBlur={() => setDraft(null)}
                        className="h-8 w-20 text-right"
                    />
                    <span className="text-muted-foreground w-16 text-xs">{Math.round(value * exchangeRate)} TND</span>
                </div>
            </div>
            <Slider
                value={[value]}
                min={0}
                max={300}
                step={1}
                disabled={disabled}
                onValueChange={([v]) => {
                    setDraft(null);
                    onChange(field, v);
                }}
            />
            {error && <p className="text-xs text-red-600 dark:text-red-400">{error}</p>}
        </div>
    );
}

export default function PriceSliders({
    minPrice,
    basePrice,
    maxPrice,
    exchangeRate,
    onChange,
    disabled = false,
    disabledReason,
    errors = {},
}: PriceSlidersProps) {
    const formatTND = (usd: number) => `${Math.round(usd * exchangeRate)} TND`;

    return (
        <div className="space-y-6">
            <PriceField
                id="yield_min_price"
                label="Prix minimum"
                help="Le prix ne descendra JAMAIS sous ce montant, même un jour très creux. Exemple : fixé à 70, une nuit calculée à 59 sera quand même vendue 70."
                field="min_price"
                value={minPrice}
                exchangeRate={exchangeRate}
                onChange={onChange}
                disabled={disabled}
                disabledReason={disabledReason}
                error={errors.min_price}
            />

            <PriceField
                id="yield_base_price"
                label="Prix de base"
                help="Le tarif d'une nuit normale. Tous les ajustements (saison, dernière minute, occupation…) partent de là. Exemple : base 100 → une nuit d'été (+40 %, ×1,40) = 140."
                field="base_price"
                value={basePrice}
                exchangeRate={exchangeRate}
                onChange={onChange}
                disabled={disabled}
                disabledReason={disabledReason}
                error={errors.base_price}
            />

            <PriceField
                id="yield_max_price"
                label="Prix maximum"
                help="Le prix ne dépassera JAMAIS ce montant, même en très forte demande. Exemple : fixé à 160, une nuit calculée à 183 sera plafonnée à 160."
                field="max_price"
                value={maxPrice}
                exchangeRate={exchangeRate}
                onChange={onChange}
                disabled={disabled}
                disabledReason={disabledReason}
                error={errors.max_price}
            />

            <div className="bg-muted/50 flex items-center justify-between rounded-lg p-3 text-sm">
                <span className="text-muted-foreground">Fourchette:</span>
                <span className="font-medium">
                    ${minPrice} – ${maxPrice} ({formatTND(minPrice)} – {formatTND(maxPrice)})
                </span>
            </div>
        </div>
    );
}
