import { formatDateTimeFr, formatRelative } from '@/lib/relative-time';
import type { ActivityEntry, ActivityPreview } from '@/types/activity';
import { extraFieldCount, fill, relatedCount, rowDetail, type Translate } from './activity-format';
import { ActionChip, ActivitySentence, ActorAvatar } from './ActivityShared';

const NS = 'activity';

const FIELD_CHIP = 'bg-background text-muted-foreground inline-flex items-center rounded border px-1.5 py-0.5 text-[11px] leading-none';

interface Props {
    entry: ActivityEntry;
    now: Date;
    locale: string;
    t: Translate;
    onOpen: (entry: ActivityEntry) => void;
    /** Porte l'ancre de la visite guidée (une seule ligne, la première du flux). */
    tourAnchor?: boolean;
}

/**
 * Ce qui a changé, lisible SANS ouvrir le panneau : « Statut : Confirmée →
 * Annulée +2 » pour une modification, les valeurs clés pour une création ou
 * une suppression. Une ligne, tronquée ; le texte complet reste en infobulle.
 */
function PreviewLine({ preview, t }: { preview: ActivityPreview; t: Translate }) {
    const empty = t(NS, 'empty_value', 'vide');

    if (preview.kind === 'values') {
        return (
            <p className="text-muted-foreground mt-1 truncate text-xs" title={preview.text}>
                {preview.text}
            </p>
        );
    }

    const label = fill(t(NS, 'preview_label', ':label :'), { label: preview.label });
    const more = preview.more > 0 ? fill(t(NS, 'more_fields', '+:count'), { count: preview.more }) : null;
    const title = `${label} ${preview.old ?? empty} → ${preview.new ?? empty}${more ? ` ${more}` : ''}`;

    return (
        <p className="mt-1 flex min-w-0 items-baseline gap-1 text-xs" title={title}>
            <span className="text-muted-foreground shrink-0">{label}</span>
            {preview.old === null ? (
                <span className="text-muted-foreground shrink-0 italic">{empty}</span>
            ) : (
                <span className="text-muted-foreground min-w-0 truncate line-through">{preview.old}</span>
            )}
            <span className="text-muted-foreground shrink-0" aria-hidden="true">
                →
            </span>
            {preview.new === null ? (
                <span className="text-muted-foreground shrink-0 italic">{empty}</span>
            ) : (
                <span className="text-foreground min-w-0 truncate font-medium">{preview.new}</span>
            )}
            {more && <span className="text-muted-foreground shrink-0">{more}</span>}
        </p>
    );
}

/**
 * Une ligne du flux = un geste humain (le serveur regroupe les écritures d'un
 * même clic). Lisible d'un coup d'œil : qui, quoi, sur quel élément, ce qui a
 * changé, quand. Tout le reste est dans le panneau de détail, ouvert au clic.
 */
export function ActivityRow({ entry, now, locale, t, onOpen, tourAnchor = false }: Props) {
    const detail = rowDetail(entry);
    const extra = extraFieldCount(entry);
    const related = relatedCount(entry);
    const parent = entry.subject.parent;

    return (
        <li>
            <button
                type="button"
                onClick={() => onOpen(entry)}
                data-tour={tourAnchor ? 'activity-row' : undefined}
                className="hover:bg-muted/50 focus-visible:ring-ring flex w-full items-start gap-3 px-3 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset sm:px-4"
            >
                <ActorAvatar actor={entry.actor} />

                <div className="min-w-0 flex-1">
                    <p className="text-sm leading-snug">
                        <ActivitySentence entry={entry} t={t} />
                        {/* L'élément parent (la réservation d'une prolongation, d'un paiement…) en
                            simple texte : pas de lien DANS le bouton de la ligne — il est au panneau. */}
                        {parent && (
                            <span className="text-muted-foreground">
                                {' · '}
                                {parent.type_label} {parent.label}
                            </span>
                        )}
                    </p>

                    {detail === 'preview' && entry.preview && <PreviewLine preview={entry.preview} t={t} />}

                    {(detail === 'fields' || related > 0) && (
                        <div className="mt-1.5 flex flex-wrap items-center gap-1">
                            {/* Repli quand le serveur n'a pas d'aperçu lisible. Deux colonnes
                                peuvent porter le même libellé traduit : la clé inclut l'index. */}
                            {detail === 'fields' &&
                                entry.summary_fields.map((field, index) => (
                                    <span key={`${index}-${field}`} className={FIELD_CHIP}>
                                        {field}
                                    </span>
                                ))}
                            {detail === 'fields' && extra > 0 && <span className={FIELD_CHIP}>{fill(t(NS, 'more_fields', '+:count'), { count: extra })}</span>}
                            {related > 0 && (
                                <span className="text-muted-foreground text-[11px]">
                                    {related === 1
                                        ? t(NS, 'related_actions_one', '+1 action liée')
                                        : fill(t(NS, 'related_actions_other', '+:count actions liées'), { count: related })}
                                </span>
                            )}
                        </div>
                    )}
                </div>

                <div className="flex shrink-0 flex-col items-end gap-1.5">
                    <time dateTime={entry.created_at} title={formatDateTimeFr(entry.created_at)} className="text-muted-foreground text-xs whitespace-nowrap">
                        {formatRelative(entry.created_at, locale, now)}
                    </time>
                    <ActionChip event={entry.event} t={t} />
                </div>
            </button>
        </li>
    );
}
