import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { formatDateFr, formatDayHeader } from '@/lib/relative-time';
import type { ActivityEntry, ActivityModule, ActivityModuleCounts, ActivityOption, ActivityPageProps, ActivityPaginator } from '@/types/activity';
import { router } from '@inertiajs/react';
import { ChevronLeft, ChevronRight, History, Info } from 'lucide-react';
import * as React from 'react';
import { fill, groupByDay, type Translate } from './activity-format';
import { ActivityModuleTabs } from './ActivityModuleTabs';
import { ActivityRow } from './ActivityRow';
import { ActivityLegend } from './ActivityShared';

const NS = 'activity';

interface Props {
    entries: ActivityPaginator;
    trackingSince: ActivityPageProps['tracking_since'];
    modules: ActivityOption[];
    moduleCounts: ActivityModuleCounts | null;
    activeModule: ActivityModule | null;
    onModule: (module: ActivityModule | null) => void;
    /** Critères qui restreignent la vue : sans eux, une liste vide n'a rien à « effacer ». */
    activeFilterCount: number;
    now: Date;
    locale: string;
    t: Translate;
    onOpen: (entry: ActivityEntry) => void;
    onReset: () => void;
}

/**
 * Le balayage : onglets de module, puis les lignes regroupées par jour, la
 * plus récente en haut. Pagination serveur (Précédent / Suivant) — le journal
 * peut compter des dizaines de milliers de lignes, rien n'est chargé d'un bloc.
 */
export function ActivityFeed({ entries, trackingSince, modules, moduleCounts, activeModule, onModule, activeFilterCount, now, locale, t, onOpen, onReset }: Props) {
    const groups = React.useMemo(() => groupByDay(entries.data), [entries.data]);
    const topRef = React.useRef<HTMLDivElement>(null);
    const tourRowId = entries.data[0]?.id ?? null;

    // La page d'après garde le défilement (preserveScroll) pour ne pas remonter
    // au-dessus des compteurs, puis ramène le HAUT du flux à l'écran.
    const goTo = (url: string | null) => {
        if (!url) return;
        router.get(
            url,
            {},
            {
                preserveState: true,
                preserveScroll: true,
                onSuccess: () => topRef.current?.scrollIntoView({ block: 'start', behavior: 'smooth' }),
            },
        );
    };

    // Honnêteté : le journal ne remonte pas avant le début du suivi. Une page
    // vide sur une période ancienne n'est pas une panne, et on le dit.
    const auditsNotice = trackingSince.audits
        ? fill(t(NS, 'tracking_audits', 'Actions suivies depuis le :date'), { date: formatDateFr(trackingSince.audits) })
        : t(NS, 'tracking_audits_none', 'Aucune action enregistrée pour le moment');
    const loginsNotice = trackingSince.logins
        ? fill(t(NS, 'tracking_logins', 'connexions suivies depuis le :date'), { date: formatDateFr(trackingSince.logins) })
        : t(NS, 'tracking_logins_none', 'connexions pas encore suivies');

    return (
        <div ref={topRef} className="flex scroll-mt-4 flex-col gap-2">
            <div
                data-tour="activity-feed"
                className="text-muted-foreground flex flex-col gap-2 text-xs lg:flex-row lg:items-center lg:justify-between"
            >
                <p className="flex items-start gap-1.5">
                    <Info className="mt-px h-3.5 w-3.5 shrink-0" aria-hidden="true" />
                    <span>
                        {auditsNotice} · {loginsNotice}
                    </span>
                </p>
                <ActivityLegend t={t} />
            </div>

            <Card className="gap-0 overflow-hidden py-0">
                <ActivityModuleTabs modules={modules} counts={moduleCounts} active={activeModule} onChange={onModule} locale={locale} t={t} />

                {groups.length === 0 ? (
                    <div className="flex flex-col items-center gap-3 px-6 py-12 text-center">
                        <History className="text-muted-foreground h-8 w-8" aria-hidden="true" />
                        <p className="text-sm font-medium">{t(NS, 'empty_title', 'Aucune action sur cette sélection')}</p>
                        <p className="text-muted-foreground max-w-md text-sm">
                            {activeFilterCount > 0
                                ? t(NS, 'empty_text', 'Élargissez la période ou retirez un filtre pour retrouver plus d’activité.')
                                : t(NS, 'empty_text_default', 'Rien n’a été enregistré sur cette période.')}
                        </p>
                        {activeFilterCount > 0 && (
                            <Button variant="outline" size="sm" onClick={onReset}>
                                {t(NS, 'clear_all', 'Tout effacer')}
                            </Button>
                        )}
                    </div>
                ) : (
                    <div className="divide-y">
                        {groups.map((group, index) => (
                            <section key={`${group.key}-${index}`} aria-label={formatDayHeader(group.firstIso, locale, now)}>
                                <h2 className="bg-muted/50 text-muted-foreground border-b px-3 py-1.5 text-xs font-medium sm:px-4">
                                    {formatDayHeader(group.firstIso, locale, now)}
                                </h2>
                                <ul className="divide-y">
                                    {group.entries.map((entry) => (
                                        <ActivityRow
                                            key={entry.id}
                                            entry={entry}
                                            now={now}
                                            locale={locale}
                                            t={t}
                                            onOpen={onOpen}
                                            tourAnchor={entry.id === tourRowId}
                                        />
                                    ))}
                                </ul>
                            </section>
                        ))}
                    </div>
                )}
            </Card>

            {(entries.prev_page_url || entries.next_page_url) && (
                <nav className="flex items-center justify-between gap-2" aria-label={t(NS, 'pagination_label', 'Pagination du journal')}>
                    <Button variant="outline" size="sm" disabled={!entries.prev_page_url} onClick={() => goTo(entries.prev_page_url)}>
                        <ChevronLeft className="mr-1 h-4 w-4" />
                        {t(NS, 'pagination_prev', 'Précédent')}
                    </Button>
                    <span className="text-muted-foreground text-sm">{fill(t(NS, 'pagination_page', 'Page :page'), { page: entries.current_page })}</span>
                    <Button variant="outline" size="sm" disabled={!entries.next_page_url} onClick={() => goTo(entries.next_page_url)}>
                        {t(NS, 'pagination_next', 'Suivant')}
                        <ChevronRight className="ml-1 h-4 w-4" />
                    </Button>
                </nav>
            )}
        </div>
    );
}
