import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useTranslation } from '@/hooks/use-translation';
import AppLayout from '@/layouts/app-layout';
import { cn } from '@/lib/utils';
import type { BreadcrumbItem } from '@/types';
import { Head, Link, useForm, usePage } from '@inertiajs/react';
import { ArrowLeft, Eye, Search } from 'lucide-react';
import { useMemo, useState } from 'react';
import HelpHint from './components/HelpHint';
import { FranchiseReadOnlyBanner } from './components/FranchiseScope';
import { useCanManageYield, useReadOnlyReason, useYieldScope } from './hooks/useYieldPermissions';
import { scopeQuery } from './lib/yield-scope';
import type { ObaPresetChoice } from './types';

interface PropertyRow {
    uid: string;
    name: string | null;
    internal_name: string | null;
    current_price: number;
    yield_status: boolean | null; // null = pas de config, true/false = config active/inactive
}

interface PageProps {
    properties: PropertyRow[];
    obaPresets: ObaPresetChoice[]; // ['conservative','recommended','aggressive'] — « Aucune » est ajoutée par l'écran
    preselect: string[];
    [key: string]: unknown;
}

const breadcrumbs: BreadcrumbItem[] = [
    { title: 'Yield Manager', href: '/yield' },
    { title: 'Activer', href: '/yield/activate' },
];

/**
 * Les textes ajoutés par l'étape « réglages honnêtes » (Conserver, aides des
 * cases, « Aucune ») passent par les MÊMES clés que la fenêtre « Règles de
 * départ » : un seul texte à tenir, en français et en anglais. Le reste de
 * l'écran est encore écrit en dur.
 */
const NS = 'yield.index';

/**
 * Le formulaire d'activation. Une case décochée DÉSACTIVE sa règle (le serveur
 * stocke la forme neutre), et « Aucune » envoie 'none'. `keep_existing_rules`
 * ne concerne que les logements déjà configurés de la sélection.
 */
type ActivateForm = {
    property_uids: string[];
    min_price: string | number;
    base_price: string | number;
    max_price: string | number;
    apply_seasonality: boolean;
    apply_last_minute: boolean;
    oba_preset: ObaPresetChoice;
    keep_existing_rules: boolean;
};

export default function YieldActivate() {
    const { properties, obaPresets, preselect } = usePage<PageProps>().props;
    const { t } = useTranslation();
    const [search, setSearch] = useState('');

    const obaLabel = (preset: ObaPresetChoice): string => {
        switch (preset) {
            case 'none':
                return t(NS, 'dialog_oba_none', 'Aucune');
            case 'conservative':
                return t(NS, 'oba_conservative', 'Conservateur');
            case 'recommended':
                return t(NS, 'oba_recommended', 'Recommandé');
            case 'aggressive':
                return t(NS, 'oba_aggressive', 'Agressif');
            default:
                return preset;
        }
    };

    // POST yield.activate.store exige yield.manage : sans elle, l'écran est
    // consultable mais l'activation est éteinte et expliquée.
    const canManage = useCanManageYield();
    const readOnlyReason = useReadOnlyReason();
    // `?coHost=` : le siège consulte une franchise — lecture seule, et le retour garde ce périmètre.
    const { coHost, readOnly } = useYieldScope();

    const { data, setData, post, processing, errors } = useForm<ActivateForm>({
        property_uids: preselect ?? [],
        min_price: '',
        base_price: '',
        max_price: '',
        apply_seasonality: true,
        apply_last_minute: true,
        oba_preset: 'recommended',
        // Cochée par défaut : réactiver ne doit pas effacer un réglage fin.
        keep_existing_rules: true,
    });

    const filtered = useMemo(() => {
        const q = search.trim().toLowerCase();
        if (!q) return properties;
        return properties.filter(
            (p) => (p.name ?? '').toLowerCase().includes(q) || (p.internal_name ?? '').toLowerCase().includes(q) || p.uid.includes(q),
        );
    }, [properties, search]);

    const selected = new Set(data.property_uids);

    // Logements de la sélection qui ont DÉJÀ une config (active ou non) — y
    // compris ceux présélectionnés par ?properties= depuis l'édition en masse.
    const { configuredCount, newCount } = useMemo(() => {
        const uids = new Set(data.property_uids);
        const chosen = properties.filter((p) => uids.has(p.uid));
        const configured = chosen.filter((p) => p.yield_status !== null).length;
        return { configuredCount: configured, newCount: chosen.length - configured };
    }, [properties, data.property_uids]);
    const keepApplies = configuredCount > 0 && data.keep_existing_rules;

    const toggle = (uid: string) => {
        const next = new Set(selected);
        if (next.has(uid)) {
            next.delete(uid);
        } else {
            next.add(uid);
        }
        setData('property_uids', Array.from(next));
    };

    const selectAllFiltered = () => {
        const next = new Set(selected);
        filtered.forEach((p) => next.add(p.uid));
        setData('property_uids', Array.from(next));
    };

    const clearSelection = () => setData('property_uids', []);

    const submit = () => {
        if (!canManage) return;
        post(route('yield.activate.store'), { preserveScroll: true });
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Activer le yield" />
            <div className="flex h-full min-w-0 flex-1 flex-col gap-4 p-3 sm:p-4 lg:p-6">
                <div className="flex flex-wrap items-center justify-between gap-2">
                    <h1 className="text-xl font-semibold">Activer le yield management</h1>
                    <Button variant="outline" asChild>
                        <Link href={route('yield.index', scopeQuery(coHost))}>
                            <ArrowLeft className="h-4 w-4" /> Retour
                        </Link>
                    </Button>
                </div>

                <FranchiseReadOnlyBanner />

                {!canManage && !readOnly && (
                    <div className="flex items-center gap-2 rounded-lg border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-900/40 dark:bg-amber-950/30 dark:text-amber-200">
                        <Eye className="h-4 w-4 shrink-0" />
                        <span>{readOnlyReason}</span>
                    </div>
                )}

                <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
                    {/* ---- Sélection des logements ---- */}
                    <Card className="lg:col-span-2">
                        <CardContent className="p-4">
                            <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
                                <div className="text-sm font-medium">
                                    Logements — {data.property_uids.length} sélectionné(s)
                                </div>
                                <div className="flex gap-2">
                                    <Button type="button" size="sm" variant="outline" onClick={selectAllFiltered}>
                                        Tout sélectionner
                                    </Button>
                                    <Button type="button" size="sm" variant="ghost" onClick={clearSelection}>
                                        Effacer
                                    </Button>
                                </div>
                            </div>

                            <div className="relative mb-3">
                                <Search className="text-muted-foreground absolute top-2.5 left-2 h-4 w-4" />
                                <Input
                                    className="pl-8"
                                    placeholder="Rechercher un logement…"
                                    value={search}
                                    onChange={(e) => setSearch(e.target.value)}
                                />
                            </div>

                            {errors.property_uids && <p className="mb-2 text-sm text-red-500">{errors.property_uids}</p>}

                            <div className="max-h-[420px] space-y-1 overflow-y-auto pr-1">
                                {filtered.length === 0 ? (
                                    <div className="text-muted-foreground py-6 text-center text-sm">Aucun logement trouvé.</div>
                                ) : (
                                    filtered.map((p) => (
                                        <label
                                            key={p.uid}
                                            className={cn(
                                                'flex cursor-pointer items-center gap-3 rounded-lg border p-2 text-sm',
                                                selected.has(p.uid) ? 'border-secondary bg-secondary/5' : 'hover:bg-muted/40',
                                            )}
                                        >
                                            <Checkbox checked={selected.has(p.uid)} onCheckedChange={() => toggle(p.uid)} />
                                            <span className="min-w-0 flex-1 truncate">
                                                {p.internal_name ? <span className="font-semibold text-emerald-600">{p.internal_name} </span> : null}
                                                {p.name ?? `#${p.uid}`}
                                            </span>
                                            {p.yield_status !== null && (
                                                <span
                                                    className={cn(
                                                        'shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium',
                                                        p.yield_status ? 'bg-emerald-100 text-emerald-700' : 'bg-muted text-muted-foreground',
                                                    )}
                                                >
                                                    {p.yield_status ? 'Yield actif' : 'Config existante'}
                                                </span>
                                            )}
                                        </label>
                                    ))
                                )}
                            </div>
                        </CardContent>
                    </Card>

                    {/* ---- Règles de départ ---- */}
                    <Card data-tour="yield-activate-rules">
                        <CardContent className="space-y-4 p-4">
                            <div className="text-sm font-medium">
                                Règles de départ
                                <HelpHint text="Réglages communs appliqués à tous les logements cochés. Tu pourras affiner chaque logement ensuite (saisons par dates, last-minute, OBA…)." />
                            </div>

                            <div className="grid grid-cols-3 gap-2">
                                <div>
                                    <Label htmlFor="min_price" className="text-xs">
                                        Min
                                        <HelpHint text="Prix plancher : jamais en dessous. Ex : 70 → une nuit calculée à 59 reste vendue 70." />
                                    </Label>
                                    <Input id="min_price" type="number" min={0} value={data.min_price} onChange={(e) => setData('min_price', e.target.value)} />
                                </div>
                                <div>
                                    <Label htmlFor="base_price" className="text-xs">
                                        Base
                                        <HelpHint text="Tarif de référence d'une nuit normale, point de départ de tous les calculs. Ex : base 100 → été (+40 %, ×1,40) = 140." />
                                    </Label>
                                    <Input id="base_price" type="number" min={0} value={data.base_price} onChange={(e) => setData('base_price', e.target.value)} />
                                </div>
                                <div>
                                    <Label htmlFor="max_price" className="text-xs">
                                        Max
                                        <HelpHint text="Prix plafond : jamais au-dessus. Ex : 160 → une nuit calculée à 183 est ramenée à 160." />
                                    </Label>
                                    <Input id="max_price" 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>
                            )}
                            <p className="text-muted-foreground text-xs">Prix par nuit (USD). Le moteur garde toujours le prix entre Min et Max.</p>

                            {configuredCount > 0 && (
                                <div className="bg-muted/30 space-y-1 rounded-lg border p-2" data-tour="yield-activate-keep">
                                    <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),
                                            )}
                                            {/* Pas de sélecteur de groupe sur cet écran (rule_group_id
                                                n'est jamais posté) : l'aide ne peut pas en promettre un,
                                                et doit dire que « Décochée » détache du groupe. */}
                                            <HelpHint
                                                text={t(
                                                    NS,
                                                    'activate_keep_existing_help',
                                                    'Cochée : pour ces logements, seuls les prix min/base/max et l’activation changent ; leurs saisons, last-minute et OBA, et leur groupe de règles, restent tels quels. Décochée : ils repartent des règles ci-dessous (saisons reprojetées à partir d’aujourd’hui, stratégie OBA choisie, case décochée = règle désactivée) et sont détachés de leur groupe de règles.',
                                                )}
                                            />
                                        </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>
                                <div className="mb-1 text-xs font-medium">
                                    {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.',
                                        )}
                                    />
                                </div>
                                <div className="flex flex-wrap gap-1.5">
                                    {(['none', ...obaPresets] as ObaPresetChoice[]).map((preset) => (
                                        <button
                                            key={preset}
                                            type="button"
                                            onClick={() => setData('oba_preset', preset)}
                                            className={cn(
                                                'rounded-full border px-3 py-1 text-xs',
                                                data.oba_preset === preset ? 'border-secondary bg-secondary text-white' : 'text-muted-foreground hover:bg-muted/40',
                                            )}
                                        >
                                            {obaLabel(preset)}
                                        </button>
                                    ))}
                                </div>
                            </div>

                            <Button
                                className="w-full"
                                disabled={processing || data.property_uids.length === 0 || !canManage}
                                title={canManage ? undefined : readOnlyReason}
                                onClick={submit}
                            >
                                Activer sur {data.property_uids.length} logement(s)
                            </Button>
                            <p className="text-muted-foreground text-xs">
                                Tu pourras affiner chaque logement ensuite (saisonnalité détaillée, last-minute, OBA, etc.) depuis sa page.
                            </p>
                        </CardContent>
                    </Card>
                </div>
            </div>
        </AppLayout>
    );
}
