import type { ReactElement } from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import ObaWindowCard from './ObaWindowCard';

/**
 * La carte d'une échéance OBA, sans DOM (environnement `node`) : le composant
 * n'a aucun hook, on l'appelle comme une fonction et on joue ses
 * gestionnaires avec des événements factices — dans l'ordre où le navigateur
 * les envoie (mousedown, PUIS le blur que ce clic provoque).
 */
type CardProps = {
    onMouseDownCapture: (e: { currentTarget: object }) => void;
    onBlur: (e: { currentTarget: object; relatedTarget: object | null }) => void;
};

function cardWith(onFocusLeave: () => void) {
    const element = ObaWindowCard({ onFocusLeave, className: 'x', children: null }) as ReactElement<CardProps>;
    const inside = { name: 'multiplicateur de la même ligne' };
    const node = { contains: (other: unknown) => other === inside };
    return { props: element.props, node, inside };
}

afterEach(() => {
    vi.useRealTimers();
});

describe('ObaWindowCard — ne signale que la SORTIE du focus', () => {
    it('Tab vers un autre champ de la carte : rien', () => {
        const onFocusLeave = vi.fn();
        const { props, node, inside } = cardWith(onFocusLeave);

        props.onBlur({ currentTarget: node, relatedTarget: inside });

        expect(onFocusLeave).not.toHaveBeenCalled();
    });

    it('focus parti ailleurs sur la page : signalé', () => {
        const onFocusLeave = vi.fn();
        const { props, node } = cardWith(onFocusLeave);

        props.onBlur({ currentTarget: node, relatedTarget: { name: 'Enregistrer' } });
        props.onBlur({ currentTarget: node, relatedTarget: null });

        expect(onFocusLeave).toHaveBeenCalledTimes(2);
    });

    it('clic sur une corbeille de la carte sous Safari (le bouton ne prend pas le focus) : rien — puis la carte oublie le clic', () => {
        vi.useFakeTimers();
        const onFocusLeave = vi.fn();
        const { props, node } = cardWith(onFocusLeave);

        // mousedown sur la corbeille, puis le blur du champ « taux » qu'il provoque, sans cible.
        props.onMouseDownCapture({ currentTarget: node });
        props.onBlur({ currentTarget: node, relatedTarget: null });
        expect(onFocusLeave).not.toHaveBeenCalled();

        // Le clic est passé : une vraie sortie plus tard est de nouveau signalée.
        vi.runAllTimers();
        props.onBlur({ currentTarget: node, relatedTarget: null });
        expect(onFocusLeave).toHaveBeenCalledTimes(1);
    });

    it('un clic dans UNE carte ne retient pas le tri d’une AUTRE carte', () => {
        vi.useFakeTimers();
        const leaveA = vi.fn();
        const a = cardWith(leaveA);
        const b = cardWith(vi.fn());

        // Focus dans la carte A, clic dans la carte B : A est bien quittée.
        b.props.onMouseDownCapture({ currentTarget: b.node });
        a.props.onBlur({ currentTarget: a.node, relatedTarget: null });

        expect(leaveA).toHaveBeenCalledTimes(1);
    });
});
