import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useTranslation } from '@/hooks/use-translation';
import AppLayout from '@/layouts/app-layout';
import { type BreadcrumbItem, type SharedData } from '@/types';
import type { AutomationPageProps, AutomationTab, RuleRow, RuleTemplate } from '@/types/automatisations';
import { Head, router, usePage } from '@inertiajs/react';
import { LayoutTemplate, Loader2, Play, Plus } from 'lucide-react';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import { AutomationKpis } from './components/AutomationKpis';
import { fill } from './components/automatisations-format';
import { HistoryTab } from './components/HistoryTab';
import { PendingTab } from './components/PendingTab';
import { duplicateRuleForm, ruleFormFromTemplate, type RuleFormData } from './components/rule-form';
import { RuleSheet } from './components/RuleSheet';
import { RulesTab } from './components/RulesTab';
import { StatusBanner } from './components/StatusBanner';
import { TemplatesDialog } from './components/TemplatesDialog';

const NS = 'automatisations';

type Flash = { type?: 'success' | 'error' | 'warning' | 'info'; message?: string } | null | undefined;

/** Horloge partagée des temps relatifs (« il y a 6 min »), rafraîchie sans recharger la page. */
function useNow(intervalMs: number): Date {
    const [now, setNow] = useState(() => new Date());

    useEffect(() => {
        const timer = window.setInterval(() => setNow(new Date()), intervalMs);
        return () => window.clearInterval(timer);
    }, [intervalMs]);

    return now;
}

/** L'adresse de la page avec l'onglet voulu, sans perdre le reste de la requête. */
function urlWithTab(tab: AutomationTab): string {
    const url = new URL(window.location.href);
    url.searchParams.set('tab', tab);

    return `${url.pathname}${url.search}`;
}

/**
 * Messages automatiques aux voyageurs — siège uniquement.
 *
 * Hiérarchie : coup d'œil (bandeau d'état, compteurs) → balayage (règles,
 * messages à valider, historique) → détail (éditeur de règle avec aperçu
 * réel, fenêtre d'un envoi).
 *
 * Contrat des props : `resources/js/types/automatisations.ts`.
 */
export default function AutomatisationsIndex() {
    const { t, locale } = useTranslation();
    const page = usePage<AutomationPageProps & SharedData & { flash?: Flash }>();
    const { rules, pending, history, counts, properties, placeholders, templates, options, health, can, tab, filters, flash } = page.props;
    const now = useNow(30_000);

    const [sheetOpen, setSheetOpen] = useState(false);
    const [editing, setEditing] = useState<RuleRow | null>(null);
    // Création depuis un modèle ou une copie : le formulaire de départ de l'éditeur.
    const [initial, setInitial] = useState<RuleFormData | null>(null);
    const [templatesOpen, setTemplatesOpen] = useState(false);
    const [deleting, setDeleting] = useState<RuleRow | null>(null);
    const [activating, setActivating] = useState<RuleRow | null>(null);
    const [confirmRun, setConfirmRun] = useState(false);
    const [running, setRunning] = useState(false);

    // « Lancer maintenant » : le passage horaire du moteur, tout de suite. Le
    // résultat revient en message (flash) et les onglets se rechargent.
    const runNow = () => {
        setConfirmRun(false);
        router.post(
            route('automatisations.run'),
            {},
            { preserveScroll: true, preserveState: true, onStart: () => setRunning(true), onFinish: () => setRunning(false) },
        );
    };

    const breadcrumbs: BreadcrumbItem[] = [{ title: t(NS, 'title', 'Automatisations'), href: '/automatisations' }];

    useEffect(() => {
        if (!flash?.message) return;
        if (flash.type === 'error') toast.error(flash.message);
        else if (flash.type === 'warning') toast.warning(flash.message);
        else if (flash.type === 'info') toast.info(flash.message);
        else toast.success(flash.message);
    }, [flash]);

    /*
     * L'onglet vit dans l'adresse (?tab=) — la cloche « messages à valider »
     * pointe sur ?tab=pending. Changer d'onglet ne recharge rien : toutes les
     * données sont déjà là, seule l'adresse est réécrite (visite côté client).
     */
    const changeTab = (next: string) => {
        if (next !== 'rules' && next !== 'pending' && next !== 'history') return;
        if (next === tab) return;
        router.replace({ url: urlWithTab(next), props: (current) => ({ ...current, tab: next }), preserveScroll: true, preserveState: true });
    };

    const openCreate = () => {
        setEditing(null);
        setInitial(null);
        setSheetOpen(true);
    };

    const openEdit = (rule: RuleRow) => {
        setEditing(rule);
        setInitial(null);
        setSheetOpen(true);
    };

    // Un modèle, une copie : l'éditeur s'ouvre en CRÉATION, pré-rempli. Rien n'est enregistré avant « Enregistrer ».
    const openFromTemplate = (template: RuleTemplate) => {
        setTemplatesOpen(false);
        setEditing(null);
        setInitial(ruleFormFromTemplate(template, options.sources));
        setSheetOpen(true);
    };

    const openDuplicate = (rule: RuleRow) => {
        setEditing(null);
        setInitial(duplicateRuleForm(rule, t(NS, 'duplicate_name', 'Copie de :name')));
        setSheetOpen(true);
    };

    const toggle = (rule: RuleRow, active: boolean) => {
        router.post(route('automatisations.rules.toggle', rule.id), { active }, { preserveScroll: true, preserveState: true });
    };

    // Allumer une règle « Automatique » fait partir des messages seuls : on le dit, et on demande.
    const requestToggle = (rule: RuleRow, active: boolean) => {
        if (active && rule.mode === 'auto') {
            setActivating(rule);
            return;
        }
        toggle(rule, active);
    };

    const destroy = (rule: RuleRow) => {
        router.delete(route('automatisations.rules.destroy', rule.id), { preserveScroll: true, preserveState: true });
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title={t(NS, 'title', 'Automatisations')} />

            {/* pb-24 : le dernier bouton d'une carte doit pouvoir remonter au-dessus du
                lanceur flottant de l'assistant (coin bas-droit). */}
            <div className="flex h-full flex-1 flex-col gap-4 p-3 pb-24 sm:p-4 sm:pb-24 lg:p-6 lg:pb-24">
                <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                    <div className="flex min-w-0 flex-col gap-2">
                        <div>
                            <h1 className="text-2xl font-semibold tracking-tight">{t(NS, 'title', 'Automatisations')}</h1>
                            <p className="text-muted-foreground text-sm">
                                {t(
                                    NS,
                                    'subtitle',
                                    'Des messages aux voyageurs, au bon moment du séjour : préparés pour votre relecture, ou envoyés seuls.',
                                )}
                            </p>
                        </div>
                        <StatusBanner health={health} now={now} locale={locale} t={t} />
                    </div>
                    {can.manage && (
                        <div className="flex shrink-0 flex-wrap gap-2 self-start">
                            <Button
                                variant="outline"
                                onClick={() => setConfirmRun(true)}
                                disabled={running}
                                aria-busy={running}
                                title={t(
                                    NS,
                                    'run_now_hint',
                                    'Fait tout de suite ce que le passage horaire ferait : prépare les messages dus et envoie ceux des règles automatiques.',
                                )}
                                data-tour="automatisations-run"
                            >
                                {running ? <Loader2 className="h-4 w-4 animate-spin" /> : <Play className="h-4 w-4" />}
                                {running ? t(NS, 'running', 'Exécution…') : t(NS, 'run_now', 'Lancer maintenant')}
                            </Button>
                            <Button variant="outline" onClick={() => setTemplatesOpen(true)} data-tour="automatisations-templates">
                                <LayoutTemplate className="h-4 w-4" />
                                {t(NS, 'templates_button', 'Modèles')}
                            </Button>
                            <Button onClick={openCreate} data-tour="automatisations-new-rule">
                                <Plus className="h-4 w-4" />
                                {t(NS, 'new_rule', 'Nouvelle règle')}
                            </Button>
                        </div>
                    )}
                </div>

                <AutomationKpis counts={counts} locale={locale} t={t} />

                <Tabs value={tab} onValueChange={changeTab} className="gap-3">
                    <TabsList className="w-full sm:w-fit">
                        <TabsTrigger value="rules" onClick={() => changeTab('rules')}>
                            {t(NS, 'tab_rules', 'Règles')}
                        </TabsTrigger>
                        {/* onClick en plus de la sélection Radix (au mousedown) : la visite guidée ouvre l'onglet par un clic programmé. */}
                        <TabsTrigger value="pending" onClick={() => changeTab('pending')} data-tour="automatisations-tab-pending">
                            {t(NS, 'tab_pending', 'À traiter')}
                            {pending.length > 0 && (
                                <span className="ml-1 rounded-full bg-amber-500 px-1.5 text-[11px] leading-5 font-semibold text-white tabular-nums">
                                    {pending.length}
                                </span>
                            )}
                        </TabsTrigger>
                        <TabsTrigger value="history" onClick={() => changeTab('history')} data-tour="automatisations-tab-history">
                            {t(NS, 'tab_history', 'Historique')}
                        </TabsTrigger>
                    </TabsList>

                    <TabsContent value="rules">
                        <RulesTab
                            rules={rules}
                            canManage={can.manage}
                            locale={locale}
                            t={t}
                            onCreate={openCreate}
                            onOpenTemplates={() => setTemplatesOpen(true)}
                            onEdit={openEdit}
                            onDuplicate={openDuplicate}
                            onDelete={setDeleting}
                            onToggle={requestToggle}
                        />
                    </TabsContent>
                    <TabsContent value="pending">
                        <PendingTab pending={pending} canApprove={can.approve} now={now} locale={locale} t={t} />
                    </TabsContent>
                    <TabsContent value="history">
                        <HistoryTab history={history} status={filters.status} now={now} locale={locale} t={t} />
                    </TabsContent>
                </Tabs>
            </div>

            {can.manage && (
                <TemplatesDialog
                    open={templatesOpen}
                    onOpenChange={setTemplatesOpen}
                    templates={templates}
                    locale={locale}
                    t={t}
                    onUse={openFromTemplate}
                />
            )}

            {can.manage && (
                <RuleSheet
                    open={sheetOpen}
                    onOpenChange={setSheetOpen}
                    rule={editing}
                    initial={initial}
                    properties={properties}
                    placeholders={placeholders}
                    triggers={options.triggers}
                    sources={options.sources}
                    locale={locale}
                    t={t}
                />
            )}

            <AlertDialog open={confirmRun} onOpenChange={setConfirmRun}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>{t(NS, 'run_confirm_title', 'Lancer le moteur maintenant ?')}</AlertDialogTitle>
                        <AlertDialogDescription>
                            {t(
                                NS,
                                'run_confirm_body',
                                'Les messages dont le moment est passé sont préparés tout de suite. Ceux des règles « Automatique » partent aux voyageurs (jamais entre 22:00 et 08:00) ; ceux « À valider » attendent votre clic dans « À traiter ». Au plus 10 envois : le reste part au passage horaire suivant.',
                            )}
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>{t(NS, 'cancel', 'Annuler')}</AlertDialogCancel>
                        <AlertDialogAction onClick={runNow}>{t(NS, 'run_confirm_action', 'Lancer')}</AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            <AlertDialog open={activating !== null} onOpenChange={(value) => !value && setActivating(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>
                            {fill(t(NS, 'activate_auto_title', 'Activer « :name » en automatique ?'), { name: activating?.name ?? '' })}
                        </AlertDialogTitle>
                        <AlertDialogDescription>
                            {t(
                                NS,
                                'activate_auto_body',
                                'Les messages partiront seuls aux voyageurs concernés, à partir de maintenant. Aucun message n’est envoyé pour les moments déjà passés.',
                            )}
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>{t(NS, 'cancel', 'Annuler')}</AlertDialogCancel>
                        <AlertDialogAction
                            onClick={() => {
                                if (activating) toggle(activating, true);
                                setActivating(null);
                            }}
                        >
                            {t(NS, 'activate_auto_action', 'Activer')}
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            <AlertDialog open={deleting !== null} onOpenChange={(value) => !value && setDeleting(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>
                            {fill(t(NS, 'delete_title', 'Supprimer la règle « :name » ?'), { name: deleting?.name ?? '' })}
                        </AlertDialogTitle>
                        <AlertDialogDescription>
                            {t(
                                NS,
                                'delete_body',
                                'Elle n’enverra plus rien : ses messages pas encore partis sont annulés. L’historique est conservé.',
                            )}
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>{t(NS, 'cancel', 'Annuler')}</AlertDialogCancel>
                        <AlertDialogAction
                            className="bg-red-600 text-white hover:bg-red-700"
                            onClick={() => {
                                if (deleting) destroy(deleting);
                                setDeleting(null);
                            }}
                        >
                            {t(NS, 'delete', 'Supprimer')}
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </AppLayout>
    );
}
