import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { useTranslation } from '@/hooks/use-translation';
import { useForm } from '@inertiajs/react';
import { useEffect } from 'react';
import { toast } from 'sonner';
import { useCanManageYield, useReadOnlyReason } from '../hooks/useYieldPermissions';
import type { ObaPresetChoice, YieldRuleGroup } from '../types';
import HelpHint from './HelpHint';

const NS = 'yield.index';

/** Sentinel for "no group" — Radix Select forbids empty option values. */
const NO_GROUP = '__none__';

interface StartingRulesDialogProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    /** Property uids the starting rules will be applied to (1 from a row, or many from the bulk bar). */
    targetUids: string[];
    /** Tenant rule groups available to link at activation. */
    ruleGroups: YieldRuleGroup[];
    /** Called after a successful activation so the parent can clear its selection. */
    onActivated?: () => void;
    /**
     * Combien des logements ciblés ont DÉJÀ une config. Au-delà de 0, la case
     * « Conserver les règles actuelles » apparaît (cochée par défaut).
     */
    configuredCount: number;
}

type StartingRulesForm = {
    property_uids: string[];
    min_price: string | number;
    base_price: string | number;
    max_price: string | number;
    apply_seasonality: boolean;
    apply_last_minute: boolean;
    /** 'none' = « Aucune » : l'OBA est désactivé. */
    oba_preset: ObaPresetChoice;
    /** Logements déjà configurés : ne changer que leurs prix et leur activation. */
    keep_existing_rules: boolean;
    rule_group_id: number | null;
};

/**
 * "Règles de départ" sheet — reuses the activation form fields (min/base/max,
 * seasonality, last-minute, OBA preset). Submits to yield.activate.store for the
 * given target uids, then toasts + clears + closes on success.
 *
 * Une case décochée DÉSACTIVE sa règle (forme neutre stockée) ; « Aucune »
 * désactive l'OBA. Les logements déjà configurés gardent leurs règles tant que
 * « Conserver » est coché : seuls leurs prix et leur activation changent.
 */
export default function StartingRulesDialog({ open, onOpenChange, targetUids, ruleGroups, onActivated, configuredCount }: StartingRulesDialogProps) {
    const { t } = useTranslation();
    const canManage = useCanManageYield();
    const readOnlyReason = useReadOnlyReason();

    const { data, setData, post, processing, errors, reset } = useForm<StartingRulesForm>({
        property_uids: targetUids,
        min_price: '',
        base_price: '',
        max_price: '',
        apply_seasonality: true,
        apply_last_minute: true,
        oba_preset: 'recommended',
        keep_existing_rules: true,
        rule_group_id: null,
    });

    const newCount = Math.max(0, targetUids.length - configuredCount);

    // Keep the form's target uids in sync with the currently selected rows.
    useEffect(() => {
        setData('property_uids', targetUids);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [targetUids]);

    // La fenêtre reste montée entre deux ouvertures et reset() n'a lieu qu'après
    // une activation réussie : une case « Conserver » décochée puis « Annuler »
    // resterait décochée pour la sélection suivante, qui écraserait alors les
    // règles de ses logements configurés. Chaque ouverture repart donc cochée.
    useEffect(() => {
        if (open) setData('keep_existing_rules', true);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [open]);

    const keepApplies = configuredCount > 0 && data.keep_existing_rules;

    const submit = () => {
        if (!canManage) return;
        post(route('yield.activate.store'), {
            preserveScroll: true,
            onSuccess: () => {
                toast.success(t(NS, 'toast_activated', 'Yield activé.'));
                reset();
                onActivated?.();
                onOpenChange(false);
            },
            onError: () => toast.error(t(NS, 'toast_error', 'Une erreur est survenue.')),
        });
    };

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent side="right" className="w-full overflow-y-auto sm:max-w-md">
                <SheetHeader>
                    <SheetTitle>{t(NS, 'dialog_title', 'Règles de départ')}</SheetTitle>
                    <SheetDescription>
                        {t(NS, 'dialog_description', 'Réglages communs appliqués à tous les logements sélectionnés.')}
                    </SheetDescription>
                </SheetHeader>

                <div className="flex flex-col gap-4 px-4">
                    <div className="grid grid-cols-3 gap-2">
                        <div>
                            <Label htmlFor="srd_min" className="text-xs">
                                {t(NS, 'dialog_min', 'Min')}
                                <HelpHint text="Prix plancher : jamais en dessous." />
                            </Label>
                            <Input
                                id="srd_min"
                                type="number"
                                min={0}
                                value={data.min_price}
                                onChange={(e) => setData('min_price', e.target.value)}
                            />
                        </div>
                        <div>
                            <Label htmlFor="srd_base" className="text-xs">
                                {t(NS, 'dialog_base', 'Base')}
                                <HelpHint text="Tarif de référence d'une nuit normale, point de départ des calculs." />
                            </Label>
                            <Input
                                id="srd_base"
                                type="number"
                                min={0}
                                value={data.base_price}
                                onChange={(e) => setData('base_price', e.target.value)}
                            />
                        </div>
                        <div>
                            <Label htmlFor="srd_max" className="text-xs">
                                {t(NS, 'dialog_max', 'Max')}
                                <HelpHint text="Prix plafond : jamais au-dessus." />
                            </Label>
                            <Input
                                id="srd_max"
                                type="number"
                                min={0}
                                value={data.max_price}
                                onChange={(e) => setData('max_price', e.target.value)}
                            />
                        </div>
                    </div>
                    {(errors.min_price || errors.base_price || errors.max_price) && (
                        <p className="text-sm text-red-500">{errors.min_price ?? errors.base_price ?? errors.max_price}</p>
                    )}
                    {errors.property_uids && <p className="text-sm text-red-500">{errors.property_uids}</p>}

                    {configuredCount > 0 && (
                        <div className="bg-muted/30 space-y-1 rounded-lg border p-2">
                            <label className="flex cursor-pointer items-start gap-2 text-sm">
                                <Checkbox
                                    className="mt-0.5"
                                    checked={data.keep_existing_rules}
                                    onCheckedChange={(v) => setData('keep_existing_rules', v === true)}
                                />
                                <span>
                                    {t(NS, 'dialog_keep_existing', 'Conserver les règles actuelles des :count logement(s) déjà configuré(s)').replace(
                                        ':count',
                                        String(configuredCount),
                                    )}
                                    <HelpHint
                                        text={t(
                                            NS,
                                            'dialog_keep_existing_help',
                                            'Cochée : pour ces logements, seuls les prix min/base/max et l’activation changent ; leurs saisons, last-minute et OBA restent tels quels, et leur groupe ne change que si vous en choisissez un. Décochée : ils repartent des règles ci-dessous et sont détachés de leur groupe de règles, sauf si vous en choisissez un.',
                                        )}
                                    />
                                </span>
                            </label>
                            {keepApplies && (
                                <p className="text-muted-foreground pl-6 text-xs">
                                    {t(NS, 'dialog_keep_existing_scope', 'Saisons, last-minute et OBA ci-dessous : seulement pour les :count logement(s) sans configuration.').replace(
                                        ':count',
                                        String(newCount),
                                    )}
                                </p>
                            )}
                        </div>
                    )}

                    <label className="flex cursor-pointer items-center gap-2 text-sm">
                        <Checkbox
                            checked={data.apply_seasonality}
                            onCheckedChange={(v) => setData('apply_seasonality', v === true)}
                        />
                        {t(NS, 'dialog_seasonality', 'Appliquer la saisonnalité (haute/basse saison)')}
                        <HelpHint
                            text={t(
                                NS,
                                'dialog_seasonality_help',
                                'Pose les saisons par défaut en dates concrètes (juillet-août +40 %, du 1er novembre au 20 décembre −15 %…). Décochée : aucune saison, le prix de base s’applique toute l’année.',
                            )}
                        />
                    </label>
                    <label className="flex cursor-pointer items-center gap-2 text-sm">
                        <Checkbox
                            checked={data.apply_last_minute}
                            onCheckedChange={(v) => setData('apply_last_minute', v === true)}
                        />
                        {t(NS, 'dialog_last_minute', 'Rabais last-minute + premium longue échéance')}
                        <HelpHint
                            text={t(
                                NS,
                                'dialog_last_minute_help',
                                'Rabais sur les nuits encore libres proches de l’arrivée (jusqu’à −30 % le jour même) et +10 % au-delà de J+60. Décochée : ni rabais ni prime.',
                            )}
                        />
                    </label>

                    <div className="flex flex-col gap-1">
                        <Label className="text-xs">
                            {t(NS, 'dialog_oba_preset', 'Stratégie occupation (OBA)')}
                            <HelpHint
                                text={t(
                                    NS,
                                    'dialog_oba_help',
                                    'Force de la hausse quand le logement se remplit : Conservateur = aucune hausse sur les nuits encore libres (ses primes n’agissent qu’à 100 %), Recommandé = équilibré, Agressif = fortes hausses. Le remplissage ne baisse jamais un prix. Aucune = l’occupation ne modifie aucun prix.',
                                )}
                            />
                        </Label>
                        <Select value={data.oba_preset} onValueChange={(v) => setData('oba_preset', v as ObaPresetChoice)}>
                            <SelectTrigger>
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="none">{t(NS, 'dialog_oba_none', 'Aucune')}</SelectItem>
                                <SelectItem value="conservative">{t(NS, 'oba_conservative', 'Conservateur')}</SelectItem>
                                <SelectItem value="recommended">{t(NS, 'oba_recommended', 'Recommandé')}</SelectItem>
                                <SelectItem value="aggressive">{t(NS, 'oba_aggressive', 'Agressif')}</SelectItem>
                            </SelectContent>
                        </Select>
                    </div>

                    {ruleGroups.length > 0 && (
                        <div className="flex flex-col gap-1">
                            <Label className="text-xs">
                                {t(NS, 'dialog_rule_group', 'Lier à un groupe de règles (optionnel)')}
                                {/* Avec « Conserver », le reste d'un logement déjà configuré vient
                                    de SES règles actuelles, pas des réglages ci-dessus. */}
                                <HelpHint
                                    text={
                                        keepApplies
                                            ? t(
                                                  NS,
                                                  'dialog_rule_group_help_keep',
                                                  'Le groupe pilote les saisons / last-minute / OBA qu’il contient. Le reste vient des réglages ci-dessus pour les logements sans configuration, et de leurs règles actuelles pour ceux dont vous conservez les règles. Modifier le groupe mettra à jour ces logements automatiquement.',
                                              )
                                            : t(
                                                  NS,
                                                  'dialog_rule_group_help',
                                                  'Le groupe pilote les saisons / last-minute / OBA qu’il contient ; le reste vient des réglages ci-dessus. Modifier le groupe mettra à jour ces logements automatiquement.',
                                              )
                                    }
                                />
                            </Label>
                            <Select
                                value={data.rule_group_id == null ? NO_GROUP : String(data.rule_group_id)}
                                onValueChange={(v) => setData('rule_group_id', v === NO_GROUP ? null : Number(v))}
                            >
                                <SelectTrigger>
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value={NO_GROUP}>{t(NS, 'dialog_rule_group_none', 'Aucun')}</SelectItem>
                                    {ruleGroups.map((g) => (
                                        <SelectItem key={g.id} value={String(g.id)}>
                                            {g.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    )}
                </div>

                <SheetFooter>
                    <Button
                        onClick={submit}
                        disabled={processing || data.property_uids.length === 0 || !canManage}
                        title={canManage ? undefined : readOnlyReason}
                    >
                        {t(NS, 'dialog_submit', 'Activer')}
                    </Button>
                    <Button variant="outline" onClick={() => onOpenChange(false)}>
                        {t(NS, 'dialog_cancel', 'Annuler')}
                    </Button>
                </SheetFooter>
            </SheetContent>
        </Sheet>
    );
}
