import { CircleCheck, Timer } from 'lucide-react';
import { useEffect, useState } from 'react';

import { useTranslation } from '@/hooks/use-translation';
import { cleaningSummary, durationLabel, joinNames, type CleaningTimes } from '@/lib/cleaning-times';

/**
 * Le ménage RÉEL, en tête du dialogue de planning (planning et tableau de bord).
 *
 * Recette A (D1) : « ce n'est pas clair et tout petit, je voudrais écrire ça en
 * clair et gros avec la durée, je veux que ce soit très explicite ». Décision
 * du 24/09 : un encadré à trois cases — Arrivée · Départ · Durée — avec qui a
 * fait le ménage, en haut du dialogue ; une mission démarrée pas finie montre
 * le même encadré en orange, « en cours depuis HH:MM ». Rien avant le
 * démarrage.
 */
export function CleaningStatusCard({ cleaning }: { cleaning?: CleaningTimes | null }) {
    const { t } = useTranslation();
    const now = useMinuteClock(cleaning?.status === 'in_progress');
    const summary = cleaningSummary(cleaning, now);
    if (!summary) return null;

    const done = summary.kind === 'done';
    const names = joinNames(summary.cleaners, t('dashboard', 'cleaning_and', 'et'));
    const minutes = done ? summary.durationMinutes : summary.elapsedMinutes;

    const tone = done
        ? 'border-emerald-300 bg-emerald-50 text-emerald-950 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-50'
        : 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-50';
    const label = done ? 'text-emerald-800 dark:text-emerald-300' : 'text-amber-800 dark:text-amber-300';

    return (
        <section className={`rounded-lg border-2 p-4 ${tone}`}>
            <p className="flex items-center gap-2 text-base font-semibold">
                {done ? <CircleCheck className="size-5 shrink-0" aria-hidden /> : <Timer className="size-5 shrink-0" aria-hidden />}
                {done
                    ? t('dashboard', 'cleaning_done', 'Ménage effectué')
                    : `${t('dashboard', 'cleaning_in_progress_since', 'Ménage en cours depuis')} ${summary.arrivedAt}`}
            </p>
            {names && (
                <p className={`mt-0.5 text-sm ${label}`}>
                    {t('dashboard', 'cleaning_by', 'par')} {names}
                </p>
            )}
            <dl className="mt-3 grid grid-cols-3 gap-3">
                <Figure label={t('dashboard', 'cleaning_arrival', 'Arrivée')} labelClass={label} value={summary.arrivedAt} />
                <Figure
                    label={t('dashboard', 'cleaning_departure', 'Départ')}
                    labelClass={label}
                    value={done ? summary.leftAt : t('dashboard', 'cleaning_not_left_yet', 'pas encore')}
                    muted={!done}
                />
                <Figure
                    label={t('dashboard', 'cleaning_duration', 'Durée')}
                    labelClass={label}
                    value={minutes === null ? '—' : durationLabel(minutes)}
                    hint={done ? undefined : t('dashboard', 'cleaning_so_far', "jusqu'ici")}
                />
            </dl>
        </section>
    );
}

function Figure({
    label,
    labelClass,
    value,
    hint,
    muted = false,
}: {
    label: string;
    labelClass: string;
    value: string;
    hint?: string;
    muted?: boolean;
}) {
    return (
        <div className="min-w-0">
            <dt className={`text-xs font-semibold tracking-wide uppercase ${labelClass}`}>{label}</dt>
            <dd className={`mt-0.5 font-bold tabular-nums ${muted ? 'text-base opacity-70' : 'text-2xl'}`}>{value}</dd>
            {hint && <dd className={`text-xs ${labelClass}`}>{hint}</dd>}
        </div>
    );
}

/**
 * « Jusqu'ici » avance tant que le dialogue reste ouvert sur un ménage en
 * cours — au CHANGEMENT de minute, comme l'horloge du poste, et non 60 s après
 * l'ouverture (la durée retarderait alors d'une minute sur l'heure affichée).
 */
function useMinuteClock(ticking: boolean): Date {
    const [now, setNow] = useState(() => new Date());

    useEffect(() => {
        if (!ticking) return;
        let interval: number | undefined;
        const tick = () => setNow(new Date());
        const timeout = window.setTimeout(
            () => {
                tick();
                interval = window.setInterval(tick, 60_000);
            },
            60_000 - (Date.now() % 60_000),
        );
        return () => {
            window.clearTimeout(timeout);
            if (interval !== undefined) window.clearInterval(interval);
        };
    }, [ticking]);

    return now;
}
