/**
 * « Finances & Caisse » : dix écrans rangés en cinq entrées de menu.
 *
 * Trois entrées regroupent des écrans voisins, affichés en onglets dans la
 * BARRE DU HAUT (`FinanceBarre`, dans AppSidebarHeader) : même place sur chaque
 * écran du groupe, quelle que soit sa mise en page. Chaque écran garde sa propre
 * adresse, donc les favoris et les liens existants marchent toujours.
 *
 * Ce qui est visible vient de `financeAcces` (App\Support\FinanceAcces), la
 * copie exacte des gardes de routes : un onglet ou une entrée qui répondrait
 * 403 n'est jamais affiché. Logique pure, testée dans `finance-navigation.test.ts`.
 */

export type EcranFinance =
    | 'revenue'
    | 'factures'
    | 'recouvrements'
    | 'paiements'
    | 'clictopay'
    | 'caisse'
    | 'depenses'
    | 'recus'
    | 'retenue'
    | 'fournisseurs';

/** Prop partagée `financeAcces` : null pour un visiteur non connecté. */
export type FinanceAcces = Record<EcranFinance, boolean>;

export type CleGroupe = 'encaissements' | 'caisse' | 'fiscalite';

export interface OngletFinance {
    ecran: EcranFinance;
    href: string;
    /** Clé de `lang/{fr,en}/sidebar.php`. */
    libelle: string;
    /** Ancre de l'étape « onglets » de la visite de CET écran (`<visite>-onglets`). */
    ancre: string;
}

export interface GroupeFinance {
    cle: CleGroupe;
    /** Clé de `lang/{fr,en}/sidebar.php`. */
    libelle: string;
    onglets: OngletFinance[];
}

export const GROUPES_FINANCE: GroupeFinance[] = [
    {
        cle: 'encaissements',
        libelle: 'finance_encaissements',
        onglets: [
            { ecran: 'recouvrements', href: '/recouvrements', libelle: 'onglet_recouvrements', ancre: 'recouvrements-onglets' },
            { ecran: 'paiements', href: '/paiements/lignes', libelle: 'onglet_paiements', ancre: 'paiements-onglets' },
            { ecran: 'clictopay', href: '/paiements/en-ligne', libelle: 'onglet_clictopay', ancre: 'clictopay-onglets' },
        ],
    },
    {
        cle: 'caisse',
        libelle: 'finance_caisse',
        onglets: [
            { ecran: 'caisse', href: '/fond-de-caisse', libelle: 'onglet_caisse', ancre: 'caisse-onglets' },
            { ecran: 'depenses', href: '/depenses', libelle: 'onglet_depenses', ancre: 'depenses-onglets' },
            { ecran: 'recus', href: '/recus', libelle: 'onglet_recus', ancre: 'recus-onglets' },
        ],
    },
    {
        cle: 'fiscalite',
        libelle: 'finance_fiscalite',
        onglets: [
            { ecran: 'retenue', href: '/retenue-source', libelle: 'onglet_retenue', ancre: 'retenue-onglets' },
            { ecran: 'fournisseurs', href: '/fournisseurs', libelle: 'onglet_fournisseurs', ancre: 'fournisseurs-onglets' },
        ],
    },
];

export function groupe(cle: CleGroupe): GroupeFinance {
    const trouve = GROUPES_FINANCE.find((g) => g.cle === cle);
    if (!trouve) throw new Error(`Groupe financier inconnu : ${cle}`);
    return trouve;
}

/** Onglets que l'utilisateur peut ouvrir, dans l'ordre du groupe. */
export function ongletsVisibles(g: GroupeFinance, acces: FinanceAcces | null | undefined): OngletFinance[] {
    return acces ? g.onglets.filter((o) => acces[o.ecran]) : [];
}

/** L'onglet d'une URL : `/paiements/lignes/42` appartient à « Paiements reçus ». */
export function ongletActif(g: GroupeFinance, chemin: string): OngletFinance | undefined {
    const sansRequete = chemin.split(/[?#]/)[0];
    return g.onglets.find((o) => sansRequete === o.href || sansRequete.startsWith(`${o.href}/`));
}

/**
 * Ce que la barre du haut affiche pour une URL : le groupe, son onglet actif et
 * les onglets permis — ou null quand il n'y a rien à choisir (écran hors
 * groupe, ou un seul écran permis dans le groupe : la barre garde son titre).
 */
export function barreFinance(
    chemin: string,
    acces: FinanceAcces | null | undefined,
): { groupe: GroupeFinance; actif: OngletFinance; onglets: OngletFinance[] } | null {
    for (const g of GROUPES_FINANCE) {
        const actif = ongletActif(g, chemin);
        if (!actif) continue;
        const onglets = ongletsVisibles(g, acces);
        return onglets.length >= 2 && onglets.includes(actif) ? { groupe: g, actif, onglets } : null;
    }
    return null;
}
