<?php

/*
|--------------------------------------------------------------------------
| Pipeline Presets - Matrice mode_pro × types_mandats × niveau_automatisation
|--------------------------------------------------------------------------
|
| Utilisé par App\Services\PipelinePresetService::apply() pour générer un
| pipeline complet (statuts + tâches auto + transitions auto) en 2 clics
| depuis le wizard "Configurer en 3 minutes".
|
| Index :
|   modes[$proMode][$mandateKey]  où :
|     - $proMode      : 'particulier' | 'independant' | 'mandataire_reseau'
|                       | 'agence_societe' | 'agence_individuelle'
|     - $mandateKey   : 'vente' | 'location' | 'vente_location'
|
| Structure d'un preset :
|   {
|     'statuses' => [
|       ['slug' => 'contact', 'name' => '...', 'color' => '#...', 'icon' => 'fa-...',
|        'category' => 'active|won|lost', 'base_status_id' => 0, 'show_in_matching' => true],
|     ],
|
| 🟥 `base_status_id` = le statut LEGACY `Lead::STATUS_*` équivalent de la colonne,
|    PAS son rang dans le pipeline (2026-09-22). Il est recopié dans `leads.status` à
|    chaque transition et lu par les checkers, les commandes planifiées, les capacités
|    et la projection entre pipelines. Valeurs admises :
|      active → 0 (À prospecter) · 1 (Estimation réalisée) · 2 (Courrier envoyé) · 3 (Mandat signé)
|      won    → 4 (Vendu / Loué) - ou 3 pour un won « mandat » historique, 0/null pour un won
|               intermédiaire de scénario (funnel de qualification)
|      lost   → 5 (Abandonné), toujours
|    Une colonne active « Compromis » vaut donc 3 (mandat signé, vente en cours) et non 4 :
|    avec 4 (= STATUS_SELLED) le checker `acte_authentique_signed` devenait vrai à l'entrée
|    dans la colonne et le lead filait en « Vendu » au fire() suivant. La règle est
|    appliquée à la création par `Lead_status::normalizeBaseStatusId()` (core-city-user).
|     'tasks_by_level' => [
|       'minimal'  => [...],   // NON SUPPORTÉ (cf. note ci-dessous)
|       'standard' => [...],   // SEUL NIVEAU SUPPORTÉ
|       'maximal'  => [...],   // NON SUPPORTÉ
|     ],
|
| ⚠ NIVEAUX D'AUTOMATISATION (2026-07-28) : seul 'standard' est supporté.
| La source de vérité est `PipelinePresetService::SUPPORTED_LEVELS` ; les endpoints
| /parametres/pipeline/{apply-preset,preset-impact} refusent (422) toute autre
| valeur, et le service normalise les appels non HTTP.
| Raison : 'minimal' fait `array_slice($TASKS, 0, 3)` (tâches sur le seul premier
| statut) et réduit les triggers à une transition → les statuts suivants n'ont NI
| tâche NI transition sortante, les leads y restent bloqués. 'maximal' n'ajoute que
| des tâches manuelles. Le sélecteur a d'ailleurs été retiré de l'UI : wizard et
| onboarding postent le `niveau_recommande` du scénario (= 'standard' pour les 8).
| Les entrées 'minimal'/'maximal' sont CONSERVÉES ici (référence + réouverture
| future) mais ne sont plus appliquées. Pour en rouvrir un : l'ajouter à
| SUPPORTED_LEVELS puis lui donner un contenu complet - le harness
| `.insights/audit-pipeline-wizard-2026-06-10/validate_configs.php` refuse tout
| niveau supporté dont un statut actif n'a pas ≥1 tâche et ≥1 transition sortante.
|     'triggers_by_level' => [
|       'minimal'  => [],
|       'standard' => [...],
|       'maximal'  => [...],
|     ],
|   }
|
| Les slugs sont internes au preset (résolus en lead_status_id à l'application).
|
*/

// =====================================================================
// Helpers pour réutiliser des blocs de statuts entre modes
// =====================================================================

$STATUSES_VENTE_PRO = [
    ['slug' => 'contact',        'name' => 'À contacter',     'color' => '#3f6ad8', 'icon' => 'fa-phone',           'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'estimation',     'name' => 'Estimation',      'color' => '#f7b924', 'icon' => 'fa-calculator',      'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'avis_valeur',    'name' => 'Avis de valeur',  'color' => '#fd7e14', 'icon' => 'fa-file-alt',        'category' => 'active', 'base_status_id' => 2, 'show_in_matching' => true],
    ['slug' => 'mandat',         'name' => 'Mandat signé',    'color' => '#3ac47d', 'icon' => 'fa-file-signature',  'category' => 'active', 'base_status_id' => 3, 'show_in_matching' => true],
    ['slug' => 'compromis',      'name' => 'Compromis',       'color' => '#16a34a', 'icon' => 'fa-handshake',       'category' => 'active', 'base_status_id' => 3, 'show_in_matching' => true],
    ['slug' => 'vente',          'name' => 'Vendu',           'color' => '#28a745', 'icon' => 'fa-trophy',          'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne',      'name' => 'Abandonné',       'color' => '#d92550', 'icon' => 'fa-times-circle',    'category' => 'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

$STATUSES_LOCATION_PRO = [
    ['slug' => 'contact',        'name' => 'À contacter',     'color' => '#3f6ad8', 'icon' => 'fa-phone',           'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'visite',         'name' => 'Visite planifiée','color' => '#f7b924', 'icon' => 'fa-calendar-check',  'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'dossier',        'name' => 'Dossier ALUR',    'color' => '#fd7e14', 'icon' => 'fa-folder-open',     'category' => 'active', 'base_status_id' => 2, 'show_in_matching' => true],
    // 2026-06-10 : « Bail signé » → « Préparation bail ». On entre dans cette colonne
    // dès le dossier complet / candidat retenu (PAS à la signature) ; ses tâches sont
    // « Préparer le bail » et « Préparer état des lieux ». Le bail réellement signé
    // fait passer en « Loué » (trigger bail_signed). L'ancien nom était mensonger.
    ['slug' => 'bail',           'name' => 'Préparation bail','color' => '#3ac47d', 'icon' => 'fa-key',             'category' => 'active', 'base_status_id' => 3, 'show_in_matching' => true],
    ['slug' => 'loue',           'name' => 'Loué',            'color' => '#28a745', 'icon' => 'fa-home',            'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne',      'name' => 'Abandonné',       'color' => '#d92550', 'icon' => 'fa-times-circle',    'category' => 'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

$STATUSES_MIXTE_PRO = [
    ['slug' => 'contact',        'name' => 'À contacter',     'color' => '#3f6ad8', 'icon' => 'fa-phone',           'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'qualification',  'name' => 'Qualification',   'color' => '#6366f1', 'icon' => 'fa-search',          'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'estimation',     'name' => 'Estimation/Visite','color' => '#f7b924','icon' => 'fa-calculator',      'category' => 'active', 'base_status_id' => 2, 'show_in_matching' => true],
    ['slug' => 'mandat_bail',    'name' => 'Mandat/Dossier',  'color' => '#fd7e14', 'icon' => 'fa-file-signature',  'category' => 'active', 'base_status_id' => 3, 'show_in_matching' => true],
    ['slug' => 'compromis_bail', 'name' => 'Compromis/Bail',  'color' => '#3ac47d', 'icon' => 'fa-handshake',       'category' => 'active', 'base_status_id' => 3, 'show_in_matching' => true],
    ['slug' => 'conclu',         'name' => 'Conclu',          'color' => '#28a745', 'icon' => 'fa-trophy',          'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne',      'name' => 'Abandonné',       'color' => '#d92550', 'icon' => 'fa-times-circle',    'category' => 'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

$STATUSES_PARTICULIER_VENTE = [
    ['slug' => 'contact',  'name' => 'Contact',     'color' => '#3f6ad8', 'icon' => 'fa-phone',     'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'visite',   'name' => 'À visiter',   'color' => '#f7b924', 'icon' => 'fa-calendar',  'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'vendu',    'name' => 'Vendu',       'color' => '#28a745', 'icon' => 'fa-trophy',    'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne','name' => 'Abandonné',   'color' => '#d92550', 'icon' => 'fa-times-circle','category'=>'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

$STATUSES_PARTICULIER_LOCATION = [
    ['slug' => 'contact',  'name' => 'Contact',     'color' => '#3f6ad8', 'icon' => 'fa-phone',     'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'visite',   'name' => 'À visiter',   'color' => '#f7b924', 'icon' => 'fa-calendar',  'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'loue',     'name' => 'Loué',        'color' => '#28a745', 'icon' => 'fa-home',      'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne','name' => 'Abandonné',   'color' => '#d92550', 'icon' => 'fa-times-circle','category'=>'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

// =====================================================================
// Helpers pour les tâches/triggers selon le niveau
// =====================================================================

// Niveau STANDARD pour pipeline VENTE pro (7 statuts)
// Couvre SELLER (vendeur, RT=2) ET BUYER (acheteur, RT=1)
$TASKS_VENTE_STANDARD = [
    // === contact : commun aux 2 types ===
    ['status_slug' => 'contact',     'title' => 'Appeler le prospect',               'due_days' => 1, 'priority' => 1, 'description' => 'Premier contact qualifiant',      'auto_complete_on' => 'contact_linked', 'requirement_type' => null],
    ['status_slug' => 'contact',     'title' => 'Définir critères et budget',         'due_days' => 2, 'priority' => 1, 'description' => 'Zone, surface, type de bien',     'auto_complete_on' => 'lead_requirement_filled', 'requirement_type' => 1],   // BUYER
    // === estimation : SELLER prépare l'éval, BUYER sélectionne biens à visiter ===
    ['status_slug' => 'estimation',  'title' => 'Préparer l\'estimation',             'due_days' => 2, 'priority' => 1, 'description' => 'Réunir les données comparables',  'auto_complete_on' => 'estimation_created', 'requirement_type' => 2],   // SELLER
    ['status_slug' => 'estimation',  'title' => 'Sélectionner les biens à visiter',   'due_days' => 2, 'priority' => 1, 'description' => 'Matching critères / stock',        'auto_complete_on' => 'match_proposed', 'requirement_type' => 1],   // BUYER
    // === avis_valeur : envoi rapport SELLER ; côté BUYER : programmer visites ===
    ['status_slug' => 'avis_valeur', 'title' => 'Envoyer l\'avis de valeur',          'due_days' => 1, 'priority' => 1, 'description' => 'Document PDF personnalisé',        'auto_complete_on' => 'avis_valeur_sent','requirement_type' => 2],   // SELLER
    ['status_slug' => 'avis_valeur', 'title' => 'Organiser les visites',              'due_days' => 3, 'priority' => 1, 'description' => 'Planning et confirmations',       'auto_complete_on' => 'visit_completed','requirement_type' => 1],   // BUYER (2026-07-28 : se coche quand la visite a eu lieu)
    // === mandat (Mandat signé) : SELLER diffuse ; BUYER pose offre ===
    ['status_slug' => 'mandat',      'title' => 'Publier l\'annonce',                 'due_days' => 5, 'priority' => 1, 'description' => 'Diffusion multi-portails',         'auto_complete_on' => 'advert_published','requirement_type' => 2],   // SELLER
    ['status_slug' => 'mandat',      'title' => 'Accompagner l\'offre d\'achat',      'due_days' => 3, 'priority' => 2, 'description' => 'Négo + lettre intention',          'auto_complete_on' => 'offer_accepted', 'requirement_type' => 1],   // BUYER
    // === compromis : commun aux 2 parties ===
    ['status_slug' => 'compromis',   'title' => 'Préparer le compromis',              'due_days' => 7, 'priority' => 2, 'description' => 'Coordination avec le notaire',     'auto_complete_on' => 'compromis_signed','requirement_type' => null],
    // === vente (won) : AUCUNE tâche - 2026-06-10 : « Émettre la note d'honoraires »
    // RETIRÉE (décision produit : pas de module facturation ni d'e-facturation dans
    // l'app → la tâche ne pouvait jamais s'auto-compléter et polluait le statut won).
];

$TRIGGERS_VENTE_STANDARD = [
    // === contact → estimation : différencié ===
    ['from_slug' => 'contact',    'to_slug' => 'estimation',  'conditions' => ['estimation_created'],     'requirement_type' => 2],   // SELLER
    ['from_slug' => 'contact',    'to_slug' => 'estimation',  'conditions' => ['contact_linked'],         'requirement_type' => 1],   // BUYER (contact rentré dans le CRM)
    // === estimation → avis_valeur : différencié ===
    ['from_slug' => 'estimation', 'to_slug' => 'avis_valeur', 'conditions' => ['avis_valeur_sent'],       'requirement_type' => 2],   // SELLER
    ['from_slug' => 'estimation', 'to_slug' => 'avis_valeur', 'conditions' => ['visit_scheduled'],        'requirement_type' => 1],   // BUYER (premières visites)
    // === avis_valeur → mandat : différencié ===
    ['from_slug' => 'avis_valeur','to_slug' => 'mandat',      'conditions' => ['mandat_signed'],          'requirement_type' => 2],   // SELLER
    ['from_slug' => 'avis_valeur','to_slug' => 'mandat',      'conditions' => ['visit_completed'],        'requirement_type' => 1],   // BUYER (visite faite)
    // === mandat → compromis : différencié ===
    ['from_slug' => 'mandat',     'to_slug' => 'compromis',   'conditions' => ['compromis_signed'],       'requirement_type' => 2],   // SELLER
    ['from_slug' => 'mandat',     'to_slug' => 'compromis',   'conditions' => ['offer_accepted'],         'requirement_type' => 1],   // BUYER (offre validée)
    // === compromis → vente : commun aux 2 parties ===
    ['from_slug' => 'compromis',  'to_slug' => 'vente',       'conditions' => ['acte_authentique_signed'],'requirement_type' => null],
    // === BACKUP : all_tasks_completed (Sprint 2026-05-22, resserré 2026-06-10) ===
    // Permet à l'agent de faire avancer le lead en cochant manuellement toutes
    // les tâches du statut courant, sans attendre l'event métier officiel.
    // Le code fire() ne déclenche qu'un seul trigger par appel → pas de conflit
    // avec les triggers métier ci-dessus (les events spécifiques fire en premier).
    //
    // Audit 2026-06-10 : les backups vers « Mandat signé » et « Compromis » sont
    // RETIRÉS - ces colonnes impliquent une signature/acceptation réelle (gate
    // contractuel). Avec les tâches auto-cochées, le backup faisait passer un
    // vendeur en « Mandat signé » dès l'envoi de l'avis de valeur, et en
    // « Compromis » dès la publication de l'annonce (registre mental + webhooks
    // CRM mensongers). Ces étapes n'avancent que sur l'event métier (mandat_signed,
    // compromis_signed / offer_accepted) ou par déplacement manuel de la carte.
    ['from_slug' => 'contact',     'to_slug' => 'estimation',  'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
    ['from_slug' => 'estimation',  'to_slug' => 'avis_valeur', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
];

// Niveau STANDARD pour pipeline LOCATION pro (6 statuts)
// Couvre LESSOR (bailleur, RT=4) ET TENANT (locataire, RT=3)
$TASKS_LOCATION_STANDARD = [
    // === contact : commun ===
    ['status_slug' => 'contact', 'title' => 'Appeler le prospect',           'due_days' => 1, 'priority' => 1, 'description' => 'Qualification du besoin',     'auto_complete_on' => 'contact_linked',  'requirement_type' => null],
    ['status_slug' => 'contact', 'title' => 'Qualifier le bien à louer',     'due_days' => 2, 'priority' => 1, 'description' => 'État, loyer, charges',        'auto_complete_on' => 'lead_requirement_filled', 'requirement_type' => 4],   // LESSOR
    ['status_slug' => 'contact', 'title' => 'Qualifier critères locataire',  'due_days' => 2, 'priority' => 1, 'description' => 'Budget, zone, surface',       'auto_complete_on' => 'lead_requirement_filled', 'requirement_type' => 3],   // TENANT
    // === visite : commun (RDV + CR) ===
    ['status_slug' => 'visite',  'title' => 'Confirmer le rendez-vous',      'due_days' => 1, 'priority' => 1, 'description' => 'SMS + email J-1',             'auto_complete_on' => 'visit_completed', 'requirement_type' => null],
    ['status_slug' => 'visite',  'title' => 'Faire le CR de visite',         'due_days' => 1, 'priority' => 1, 'description' => 'Retour qualitatif',           'auto_complete_on' => 'visit_report_filled', 'requirement_type' => null],
    // === dossier : TENANT collecte, LESSOR sélectionne ===
    // (Le garant n'est pas universel - invitation à la demande via le bouton "Inviter un garant",
    //  pas de tâche par défaut. 2026-06-09 : "Vérifier garant" retirée.)
    ['status_slug' => 'dossier', 'title' => 'Demander pièces ALUR',          'due_days' => 2, 'priority' => 2, 'description' => '11 documents obligatoires',    'auto_complete_on' => 'demande_pieces_sent','requirement_type' => 3],   // TENANT
    ['status_slug' => 'dossier', 'title' => 'Présélectionner les candidats', 'due_days' => 5, 'priority' => 1, 'description' => 'Scoring dossiers reçus',      'auto_complete_on' => 'contact_selected','requirement_type' => 4],   // LESSOR
    // === bail : LESSOR rédige, commun pour EDL ===
    // 2026-06-10 : auto_complete_on bail_signed → bail_generated (la tâche « Préparer
    // le bail » se coche à la GÉNÉRATION du bail, pas à sa signature - la signature
    // est portée par la transition bail → loue).
    ['status_slug' => 'bail',    'title' => 'Préparer le bail',              'due_days' => 3, 'priority' => 1, 'description' => 'Rédaction + signature',       'auto_complete_on' => 'bail_generated',  'requirement_type' => 4],   // LESSOR
    ['status_slug' => 'bail',    'title' => 'Préparer état des lieux',       'due_days' => 5, 'priority' => 1, 'description' => 'Convocation entrée',          'auto_complete_on' => 'etat_lieux_created', 'requirement_type' => null],
    // === loue (won) : AUCUNE tâche - 2026-06-10 : « Émettre note d'honoraires »
    // RETIRÉE (pas de module facturation dans l'app, cf. statut vente du preset vente).
];

$TRIGGERS_LOCATION_STANDARD = [
    // === contact → visite : commun aux 2 (visite planifiée) ===
    ['from_slug' => 'contact',  'to_slug' => 'visite',  'conditions' => ['visit_scheduled'],     'requirement_type' => null],
    // === visite → dossier : commun (visite faite) ===
    ['from_slug' => 'visite',   'to_slug' => 'dossier', 'conditions' => ['visit_completed'],     'requirement_type' => null],
    // === dossier → bail : différencié par type ===
    ['from_slug' => 'dossier',  'to_slug' => 'bail',    'conditions' => ['demande_pieces_sent'], 'requirement_type' => 3],   // TENANT (dossier ALUR envoyé)
    ['from_slug' => 'dossier',  'to_slug' => 'bail',    'conditions' => ['contact_selected'],    'requirement_type' => 4],   // LESSOR (candidat sélectionné)
    // === bail → loue : commun ===
    ['from_slug' => 'bail',     'to_slug' => 'loue',    'conditions' => ['bail_signed'],         'requirement_type' => null],
    // === BACKUP all_tasks_completed (Sprint 2026-05-22) ===
    ['from_slug' => 'contact',  'to_slug' => 'visite',  'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
    ['from_slug' => 'visite',   'to_slug' => 'dossier', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
    ['from_slug' => 'dossier',  'to_slug' => 'bail',    'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
];

// =====================================================================
// Preset HYBRIDE Vente + Location : 7 statuts à labels duels
// (utilise $STATUSES_MIXTE_PRO : contact, qualification, estimation, mandat_bail,
// compromis_bail, conclu, abandonne)
//
// Stratégie : statuts génériques + tâches/triggers différenciés par
// requirement_type (déjà géré par Lead_status_trigger::fire et
// HasLeadHub::autoCreateTasksForStatus). Ainsi un lead vendeur reçoit
// uniquement les tâches/transitions vente, un locataire celles de location.
// =====================================================================

$TASKS_MIXTE_STANDARD = [
    // === contact : commun aux 4 types ===
    ['status_slug' => 'contact',       'title' => 'Appeler le prospect',                 'due_days' => 1, 'priority' => 1, 'description' => 'Premier contact qualifiant',     'auto_complete_on' => 'contact_linked', 'requirement_type' => null],
    // === qualification : commun + spécifique acheteur (besoin clair de critères) ===
    ['status_slug' => 'qualification', 'title' => 'Qualifier le besoin et le budget',     'due_days' => 2, 'priority' => 1, 'description' => 'Définir critères, zone, timing','auto_complete_on' => 'lead_requirement_filled', 'requirement_type' => null],
    ['status_slug' => 'qualification', 'title' => 'Définir critères acheteur',            'due_days' => 2, 'priority' => 1, 'description' => 'Zone, budget, surface, type',   'auto_complete_on' => 'lead_requirement_filled', 'requirement_type' => 1],   // BUYER

    // === estimation (Estimation/Visite) : différencié par les 4 types ===
    // 2026-06-10 : auto_complete_on avis_valeur_sent → estimation_created (aligné sur le
    // preset vente : la tâche se coche quand l'estimation est créée ; l'envoi de l'avis
    // est porté par la transition estimation → mandat_bail).
    ['status_slug' => 'estimation',    'title' => 'Préparer l\'estimation',              'due_days' => 2, 'priority' => 1, 'description' => 'Comparables + visite du bien',  'auto_complete_on' => 'estimation_created','requirement_type' => 2],   // SELLER
    ['status_slug' => 'estimation',    'title' => 'Sélectionner biens à proposer',       'due_days' => 2, 'priority' => 1, 'description' => 'Matching critères / stock',     'auto_complete_on' => 'match_proposed', 'requirement_type' => 1],   // BUYER
    ['status_slug' => 'estimation',    'title' => 'Confirmer le RDV de visite',          'due_days' => 1, 'priority' => 1, 'description' => 'SMS + email J-1',               'auto_complete_on' => 'visit_completed','requirement_type' => 4],   // LESSOR
    ['status_slug' => 'estimation',    'title' => 'Confirmer le RDV de visite',          'due_days' => 1, 'priority' => 1, 'description' => 'Confirmer et effectuer la visite du bien', 'auto_complete_on' => 'visit_completed', 'requirement_type' => 3],   // TENANT

    // === mandat_bail (Mandat/Dossier) : différencié par les 4 types ===
    ['status_slug' => 'mandat_bail',   'title' => 'Faire signer le mandat',              'due_days' => 3, 'priority' => 1, 'description' => 'Mandat de vente eIDAS',         'auto_complete_on' => 'mandat_signed',    'requirement_type' => 2],   // SELLER
    ['status_slug' => 'mandat_bail',   'title' => 'Publier l\'annonce',                  'due_days' => 5, 'priority' => 1, 'description' => 'Diffusion multi-portails',      'auto_complete_on' => 'advert_published', 'requirement_type' => 2],   // SELLER
    ['status_slug' => 'mandat_bail',   'title' => 'Accompagner l\'offre d\'achat',       'due_days' => 3, 'priority' => 2, 'description' => 'Négo + lettre intention',       'auto_complete_on' => 'offer_accepted',   'requirement_type' => 1],   // BUYER
    ['status_slug' => 'mandat_bail',   'title' => 'Collecter le dossier ALUR',           'due_days' => 3, 'priority' => 2, 'description' => '11 documents obligatoires',     'auto_complete_on' => 'demande_pieces_sent','requirement_type' => 3], // TENANT
    ['status_slug' => 'mandat_bail',   'title' => 'Présélectionner les candidats',       'due_days' => 5, 'priority' => 1, 'description' => 'Scoring dossiers reçus',        'auto_complete_on' => 'contact_selected', 'requirement_type' => 4],   // LESSOR

    // === compromis_bail (Compromis/Bail) : différencié par les 4 types ===
    ['status_slug' => 'compromis_bail','title' => 'Préparer le compromis',               'due_days' => 7, 'priority' => 2, 'description' => 'Coordination notaire',          'auto_complete_on' => 'compromis_signed', 'requirement_type' => 2],   // SELLER
    ['status_slug' => 'compromis_bail','title' => 'Coordonner notaire acheteur',         'due_days' => 7, 'priority' => 2, 'description' => 'Signature + financement',       'auto_complete_on' => 'compromis_signed', 'requirement_type' => 1],   // BUYER
    ['status_slug' => 'compromis_bail','title' => 'Préparer le bail',                    'due_days' => 5, 'priority' => 1, 'description' => 'Rédaction + signature',         'auto_complete_on' => 'bail_generated',   'requirement_type' => 4],   // LESSOR
    ['status_slug' => 'compromis_bail','title' => 'État des lieux d\'entrée',            'due_days' => 3, 'priority' => 1, 'description' => 'Convocation entrée',            'auto_complete_on' => 'etat_lieux_created', 'requirement_type' => 4],   // LESSOR
    ['status_slug' => 'compromis_bail','title' => 'Signer le bail locataire',            'due_days' => 5, 'priority' => 1, 'description' => 'Signature électronique',        'auto_complete_on' => 'bail_signed',      'requirement_type' => 3],   // TENANT

    // === conclu (won) : AUCUNE tâche - 2026-06-10 : « Émettre la note d'honoraires »
    // RETIRÉE (pas de module facturation dans l'app, cf. statut vente du preset vente).
];

$TRIGGERS_MIXTE_STANDARD = [
    // === transitions communes ===
    ['from_slug' => 'contact',        'to_slug' => 'qualification',  'conditions' => ['contact_linked'],          'requirement_type' => null],
    // === Vers Estimation/Visite : différencié par les 4 types ===
    // 2026-06-10 : BUYER contact_selected → lead_requirement_filled. L'ancien event
    // (« Contact retenu ») n'arrive quasiment jamais sur un lead acheteur en
    // qualification → impasse ; le signal métier est « critères/budget renseignés »,
    // cohérent avec sa tâche « Définir critères acheteur ».
    ['from_slug' => 'qualification',  'to_slug' => 'estimation',     'conditions' => ['estimation_created'],      'requirement_type' => 2],   // SELLER : estimation créée
    ['from_slug' => 'qualification',  'to_slug' => 'estimation',     'conditions' => ['lead_requirement_filled'], 'requirement_type' => 1],   // BUYER : critères renseignés
    ['from_slug' => 'qualification',  'to_slug' => 'estimation',     'conditions' => ['visit_scheduled'],         'requirement_type' => 4],   // LESSOR : visite planifiée
    ['from_slug' => 'qualification',  'to_slug' => 'estimation',     'conditions' => ['visit_scheduled'],         'requirement_type' => 3],   // TENANT : visite planifiée
    // === Vers Mandat/Dossier : différencié par les 4 types ===
    ['from_slug' => 'estimation',     'to_slug' => 'mandat_bail',    'conditions' => ['avis_valeur_sent'],        'requirement_type' => 2],   // SELLER : avis valeur envoyé
    ['from_slug' => 'estimation',     'to_slug' => 'mandat_bail',    'conditions' => ['visit_completed'],         'requirement_type' => 1],   // BUYER : visite faite
    ['from_slug' => 'estimation',     'to_slug' => 'mandat_bail',    'conditions' => ['visit_completed'],         'requirement_type' => 4],   // LESSOR : visite faite
    ['from_slug' => 'estimation',     'to_slug' => 'mandat_bail',    'conditions' => ['visit_completed'],         'requirement_type' => 3],   // TENANT : visite faite
    // === Vers Compromis/Bail : différencié par les 4 types ===
    ['from_slug' => 'mandat_bail',    'to_slug' => 'compromis_bail', 'conditions' => ['mandat_signed'],           'requirement_type' => 2],   // SELLER : mandat signé
    ['from_slug' => 'mandat_bail',    'to_slug' => 'compromis_bail', 'conditions' => ['offer_accepted'],          'requirement_type' => 1],   // BUYER : offre validée
    ['from_slug' => 'mandat_bail',    'to_slug' => 'compromis_bail', 'conditions' => ['contact_selected'],        'requirement_type' => 4],   // LESSOR : candidat sélectionné
    ['from_slug' => 'mandat_bail',    'to_slug' => 'compromis_bail', 'conditions' => ['demande_pieces_sent'],     'requirement_type' => 3],   // TENANT : dossier ok
    // === Vers Conclu : différencié par les 4 types ===
    ['from_slug' => 'compromis_bail', 'to_slug' => 'conclu',         'conditions' => ['acte_authentique_signed'], 'requirement_type' => 2],   // SELLER : acte signé
    ['from_slug' => 'compromis_bail', 'to_slug' => 'conclu',         'conditions' => ['acte_authentique_signed'], 'requirement_type' => 1],   // BUYER : acte signé
    ['from_slug' => 'compromis_bail', 'to_slug' => 'conclu',         'conditions' => ['bail_signed'],             'requirement_type' => 4],   // LESSOR : bail signé
    ['from_slug' => 'compromis_bail', 'to_slug' => 'conclu',         'conditions' => ['bail_signed'],             'requirement_type' => 3],   // TENANT : bail signé
    // === BACKUP all_tasks_completed (ajouté 2026-06-10, aligné vente/location) ===
    // Sur les 4 étapes actives uniquement - JAMAIS vers « Conclu » (won = uniquement
    // sur acte/bail signé ou clôture explicite). NB : mandat_bail → compromis_bail en
    // backup est sûr : les tâches de mandat_bail incluent « Faire signer le mandat »
    // (auto-cochée par mandat_signed), donc all_tasks implique le mandat signé - sauf
    // cochage manuel volontaire de l'agent (philosophie assumée du backup).
    ['from_slug' => 'contact',        'to_slug' => 'qualification',  'conditions' => ['all_tasks_completed'],     'requirement_type' => null],
    ['from_slug' => 'qualification',  'to_slug' => 'estimation',     'conditions' => ['all_tasks_completed'],     'requirement_type' => null],
    ['from_slug' => 'estimation',     'to_slug' => 'mandat_bail',    'conditions' => ['all_tasks_completed'],     'requirement_type' => null],
    ['from_slug' => 'mandat_bail',    'to_slug' => 'compromis_bail', 'conditions' => ['all_tasks_completed'],     'requirement_type' => null],
];

// Bloc statuts hybride pour mode "particulier" (plus simple : 5 statuts)
$STATUSES_PARTICULIER_MIXTE = [
    ['slug' => 'contact',     'name' => 'Contact',         'color' => '#3f6ad8', 'icon' => 'fa-phone',          'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'visite',      'name' => 'À visiter',       'color' => '#f7b924', 'icon' => 'fa-calendar',       'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'engagement',  'name' => 'Engagé',          'color' => '#fd7e14', 'icon' => 'fa-file-signature', 'category' => 'active', 'base_status_id' => 2, 'show_in_matching' => true],
    ['slug' => 'conclu',      'name' => 'Conclu',          'color' => '#28a745', 'icon' => 'fa-trophy',         'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne',   'name' => 'Abandonné',       'color' => '#d92550', 'icon' => 'fa-times-circle',   'category' => 'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

// =====================================================================
// Preset PRESTATAIRE_SERVICES : 5 statuts - funnel de PROSPECTION jusqu'au RDV technique
// (couvre photovoltaïque, électricien, plombier, notaire, télécom, bornes, etc.)
// InfoParcelle = outil de prospection : son rôle s'arrête au RDV technique (qui permettra
// d'établir le devis). Le devis / contrat / chantier / facture vivent dans les outils de
// l'artisan → on NE LES GÈRE PAS ici (2026-06-09 : suppression des statuts Devis envoyé,
// Contrat signé, Livré/Réalisé). Aucune référence à Hoguet/mandats/avis de valeur.
// =====================================================================
$STATUSES_PRESTATAIRE_PRO = [
    ['slug' => 'prospect',     'name' => 'Prospect identifié',           'color' => '#3f6ad8', 'icon' => 'fa-bullseye',      'category' => 'active', 'base_status_id' => 0, 'show_in_matching' => true],
    ['slug' => 'contacte',     'name' => 'Contacté',                     'color' => '#6366f1', 'icon' => 'fa-phone',         'category' => 'active', 'base_status_id' => 1, 'show_in_matching' => true],
    ['slug' => 'rdv_technique','name' => 'RDV technique',                'color' => '#f7b924', 'icon' => 'fa-calendar-check','category' => 'active', 'base_status_id' => 2, 'show_in_matching' => true],
    ['slug' => 'rdv_realise',  'name' => 'RDV réalisé - devis à établir', 'color' => '#28a745', 'icon' => 'fa-trophy',       'category' => 'won',    'base_status_id' => 4, 'show_in_matching' => false],
    ['slug' => 'abandonne',    'name' => 'Abandonné',                    'color' => '#d92550', 'icon' => 'fa-times-circle',  'category' => 'lost',   'base_status_id' => 5, 'show_in_matching' => false],
];

$TASKS_PRESTATAIRE_STANDARD = [
    // === prospect : prise de contact ===
    // Pas de courrier postal (email/SMS only) + prospect cadastre souvent sans coordonnées → la
    // 1re action est souvent une visite terrain pour récupérer email/tél. La tâche se coche quand
    // le prospect devient JOIGNABLE (contact_has_email_or_phone).
    // (Pas de tâche "Recherche cadastre" : l'artisan consulte la fiche parcelle naturellement au besoin - 2026-06-09.)
    ['status_slug' => 'prospect',     'title' => 'Prendre contact (sur place, email ou SMS)', 'due_days' => 1, 'priority' => 1, 'description' => 'Récupérer email ou téléphone du prospect', 'auto_complete_on' => 'contact_has_email_or_phone', 'requirement_type' => null],
    // === contacte : qualifier + planifier le RDV technique ===
    ['status_slug' => 'contacte',     'title' => 'Qualifier le besoin et planifier le RDV technique', 'due_days' => 2, 'priority' => 1, 'description' => 'Découverte du besoin + prise de RDV', 'auto_complete_on' => 'visit_scheduled', 'requirement_type' => null],
    // === rdv_technique : réaliser le RDV (qui permettra d'établir le devis) ===
    ['status_slug' => 'rdv_technique','title' => 'Réaliser le RDV technique',                 'due_days' => 3, 'priority' => 1, 'description' => 'Visite sur place pour relever et chiffrer', 'auto_complete_on' => 'visit_completed', 'requirement_type' => null],
];

$TASKS_PRESTATAIRE_MAXIMAL = array_merge($TASKS_PRESTATAIRE_STANDARD, [
    // Tâches optionnelles (manuelles) - relance + préparation du RDV.
    ['status_slug' => 'contacte',     'title' => 'Relance J+3 si pas de retour',                  'due_days' => 3, 'priority' => 1, 'description' => '', 'auto_complete_on' => null, 'requirement_type' => null],
    ['status_slug' => 'rdv_technique','title' => 'Préparer la visite technique (matériel, accès)','due_days' => 1, 'priority' => 0, 'description' => '', 'auto_complete_on' => null, 'requirement_type' => null],
]);

$TRIGGERS_PRESTATAIRE_STANDARD = [
    // Funnel NON-immobilier (prospection jusqu'au RDV technique). Chaque étape avance sur un event
    // GÉNÉRIQUE + un backup all_tasks_completed (avancement manuel possible). Aucun event immobilier
    // (mandat/bail/compromis/devis/facture) : ils ne se déclencheraient jamais pour un prestataire.
    // Prospect→Contacté sur `contact_has_email_or_phone` (PAS `contact_linked`) : un contact SANS
    // email/téléphone (cas artisan avant la visite terrain) ne fait pas passer en "Contacté" alors
    // qu'il est injoignable - il avance quand on a récupéré ses coordonnées.
    ['from_slug' => 'prospect',     'to_slug' => 'contacte',      'conditions' => ['contact_has_email_or_phone'], 'requirement_type' => null],
    ['from_slug' => 'prospect',     'to_slug' => 'contacte',      'conditions' => ['all_tasks_completed'],        'requirement_type' => null],
    ['from_slug' => 'contacte',     'to_slug' => 'rdv_technique', 'conditions' => ['visit_scheduled'],            'requirement_type' => null],
    ['from_slug' => 'contacte',     'to_slug' => 'rdv_technique', 'conditions' => ['all_tasks_completed'],        'requirement_type' => null],
    // RDV réalisé → statut "gagné" : le prospect est qualifié, l'artisan établit son devis hors-outil.
    ['from_slug' => 'rdv_technique','to_slug' => 'rdv_realise',   'conditions' => ['visit_completed'],            'requirement_type' => null],
    ['from_slug' => 'rdv_technique','to_slug' => 'rdv_realise',   'conditions' => ['all_tasks_completed'],        'requirement_type' => null],
];

// =====================================================================
// Matrice complète
// =====================================================================

return [
    /*
    | Liste plate des modes pour la UI
    */
    'pro_mode_labels' => [
        'particulier'           => 'Particulier',
        'independant'           => 'Agent immobilier indépendant',
        'mandataire_reseau'     => 'Mandataire affilié à un réseau',
        'agence_societe'        => 'Agence (société)',
        'agence_individuelle'   => 'Agence individuelle',
        'prestataire_services'  => 'Prestataire de services',
    ],

    /*
    | Catégories d'activité métier pour le mode 'prestataire_services'.
    | Stockées dans core.user_legal_notices.activity_category.
    | Groupées par famille (clé = label HTML <optgroup>, valeur = slug => label).
    */
    'activity_categories' => [
        '🏢 Foncier & immobilier non-agent' => [
            'promoteur_immobilier' => 'Promoteur immobilier',
            'bailleur_social'      => 'Bailleur social / HLM',
            'scpi_fonds'           => 'SCPI / Fonds d\'investissement immo',
            'marchand_biens'       => 'Marchand de biens / Investisseur',
        ],
        '⚡ Énergie & rénovation' => [
            'photovoltaique'       => 'Installateur panneaux solaires',
            'bornes_recharge'      => 'Bornes de recharge électrique',
            'pompe_chaleur'        => 'Pompes à chaleur / Chauffage',
            'auditeur_energetique' => 'Auditeur énergétique / Rénovation',
            'isolation'            => 'Isolation / ITE / Rénovation globale',
            'methanisation_eolien' => 'Méthanisation / Éolien / Géothermie',
        ],
        '🏗 Bâtiment & travaux' => [
            'electricien'        => 'Électricien / Domotique',
            'plombier'           => 'Plombier / Sanitaire',
            'couvreur'           => 'Couvreur / Charpente',
            'climaticien'        => 'Climatisation / CVC',
            'facade_ravalement'  => 'Façadier / Ravalement / ITE',
            'menuisier'          => 'Menuisier / Fenêtres',
            'maconnerie'         => 'Maçonnerie / Gros œuvre',
            'piscine_spa'        => 'Piscine / Spa',
        ],
        '🚗 Mobilité & infrastructures' => [
            'telecom'          => 'Télécom / Fibre / Antennes',
            'parking_mobilite' => 'Parking / Mobilité urbaine',
            'logistique'       => 'Logistique / Entreposage',
        ],
        '💼 Conseil & expertise' => [
            'notaire'             => 'Notaire',
            'architecte'          => 'Architecte',
            'geometre_expert'     => 'Géomètre-expert',
            'bureau_etudes'       => 'Bureau d\'études techniques',
            'diagnostiqueur'      => 'Diagnostiqueur (DPE, amiante, plomb)',
            'expert_judiciaire'   => 'Expert immobilier / Judiciaire',
            'environnementaliste' => 'Environnementaliste / Géologue',
        ],
        '🌱 Agriculture & environnement' => [
            'agriculture_foncier' => 'Foncier agricole / Exploitant',
            'forestier'           => 'Gestionnaire forestier',
        ],
        '🛒 Commerce & emplacements' => [
            'retail_emplacement' => 'Implantation retail / Distribution',
            'hotellerie_camping' => 'Hôtellerie / Camping / Gîte',
        ],
        '💳 Finance & assurance' => [
            'banque_credit'        => 'Banque / Crédit immobilier',
            'assurance_habitation' => 'Assurance habitation',
        ],
        '🔧 Tech & data' => [
            'developpeur_api' => 'Développeur / Intégrateur API',
        ],
        '📋 Autre' => [
            'autre' => 'Autre métier non immobilier',
        ],
    ],

    /*
    | Modes pro × types de mandats
    | NB : si une combinaison spécifique n'existe pas, le service retombe sur
    | 'independant' du même mandat_key. Si elle n'existe pas non plus, retombe
    | sur 'independant' / 'vente'.
    */
    'modes' => [

        // ============== PARTICULIER (simplifié) ==============
        'particulier' => [
            'vente' => [
                'statuses' => $STATUSES_PARTICULIER_VENTE,
                'tasks_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['status_slug' => 'contact', 'title' => 'Rappeler le prospect', 'due_days' => 1, 'priority' => 1, 'description' => '', 'auto_complete_on' => 'contact_linked'],
                        ['status_slug' => 'visite',  'title' => 'Préparer la visite',   'due_days' => 2, 'priority' => 0, 'description' => '', 'auto_complete_on' => 'visit_completed'],
                    ],
                    'maximal'  => [
                        ['status_slug' => 'contact', 'title' => 'Rappeler le prospect',      'due_days' => 1, 'priority' => 1, 'description' => '',                       'auto_complete_on' => 'contact_linked'],
                        ['status_slug' => 'contact', 'title' => 'Relance si pas de réponse', 'due_days' => 3, 'priority' => 1, 'description' => '',                       'auto_complete_on' => null],
                        ['status_slug' => 'visite',  'title' => 'Préparer la visite',        'due_days' => 2, 'priority' => 0, 'description' => '',                       'auto_complete_on' => 'visit_completed'],
                        ['status_slug' => 'visite',  'title' => 'Faire un CR de visite',     'due_days' => 1, 'priority' => 1, 'description' => 'Retour qualitatif',       'auto_complete_on' => null],
                    ],
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['visit_scheduled'], 'requirement_type' => null],
                        // Sprint 2026-05-22 - Trigger won manquant en standard
                        ['from_slug' => 'visite',  'to_slug' => 'vendu',  'conditions' => ['acte_authentique_signed'], 'requirement_type' => null],
                        // BACKUP all_tasks_completed
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
                    ],
                    'maximal'  => [
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['visit_scheduled'], 'requirement_type' => null],
                        ['from_slug' => 'visite',  'to_slug' => 'vendu',  'conditions' => ['acte_authentique_signed'], 'requirement_type' => null],
                        // BACKUP all_tasks_completed - uniquement vers les étapes actives.
                        // 2026-06-10 : backup visite → vendu RETIRÉ (cocher « Préparer la
                        // visite » + « Faire un CR » ne doit jamais marquer le bien VENDU ;
                        // le won n'avance que sur acte signé ou clôture explicite).
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
                    ],
                ],
            ],
            'location' => [
                'statuses' => $STATUSES_PARTICULIER_LOCATION,
                'tasks_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['status_slug' => 'contact', 'title' => 'Rappeler le candidat',   'due_days' => 1, 'priority' => 1, 'description' => '', 'auto_complete_on' => 'contact_linked'],
                        ['status_slug' => 'visite',  'title' => 'Préparer la visite',     'due_days' => 2, 'priority' => 0, 'description' => '', 'auto_complete_on' => 'visit_completed'],
                    ],
                    'maximal'  => [
                        ['status_slug' => 'contact', 'title' => 'Rappeler le candidat',         'due_days' => 1, 'priority' => 1, 'description' => '', 'auto_complete_on' => 'contact_linked'],
                        ['status_slug' => 'contact', 'title' => 'Demander pièces d\'identité',  'due_days' => 2, 'priority' => 1, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'visite',  'title' => 'Préparer la visite',           'due_days' => 2, 'priority' => 0, 'description' => '', 'auto_complete_on' => 'visit_completed'],
                    ],
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['visit_scheduled'], 'requirement_type' => null],
                        // Sprint 2026-05-22 - Trigger won manquant en standard
                        ['from_slug' => 'visite',  'to_slug' => 'loue',   'conditions' => ['bail_signed'],     'requirement_type' => null],
                        // BACKUP all_tasks_completed
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
                    ],
                    'maximal'  => [
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['visit_scheduled'], 'requirement_type' => null],
                        ['from_slug' => 'visite',  'to_slug' => 'loue',   'conditions' => ['bail_signed'],     'requirement_type' => null],
                        // BACKUP all_tasks_completed - uniquement vers les étapes actives.
                        // 2026-06-10 : backup visite → loue RETIRÉ (même règle que la vente :
                        // le won n'avance que sur bail signé ou clôture explicite).
                        ['from_slug' => 'contact', 'to_slug' => 'visite', 'conditions' => ['all_tasks_completed'], 'requirement_type' => null],
                    ],
                ],
            ],
            // Mode mixte simplifié pour particulier (5 statuts, pas de Hoguet)
            'vente_location' => [
                'statuses' => $STATUSES_PARTICULIER_MIXTE,
                'tasks_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['status_slug' => 'contact',    'title' => 'Rappeler le prospect',  'due_days' => 1, 'priority' => 1, 'description' => '', 'auto_complete_on' => 'contact_linked', 'requirement_type' => null],
                        ['status_slug' => 'visite',     'title' => 'Préparer la visite',    'due_days' => 2, 'priority' => 0, 'description' => '', 'auto_complete_on' => 'visit_completed',             'requirement_type' => null],
                        // 2026-07-28 - Remontée du niveau maximal : le statut « Engagé »
                        // n'avait AUCUNE tâche en standard, donc aucune progression
                        // affichable dans le kanban (détecté par validate_configs.php).
                        ['status_slug' => 'engagement', 'title' => 'Demander les pièces au candidat',  'due_days' => 5, 'priority' => 1, 'description' => 'Pièces justificatives', 'auto_complete_on' => 'demande_pieces_sent',             'requirement_type' => null],
                    ],
                    'maximal'  => [
                        ['status_slug' => 'contact',    'title' => 'Rappeler le prospect',      'due_days' => 1, 'priority' => 1, 'description' => '', 'auto_complete_on' => 'contact_linked', 'requirement_type' => null],
                        ['status_slug' => 'contact',    'title' => 'Relance si pas de réponse', 'due_days' => 3, 'priority' => 1, 'description' => '', 'auto_complete_on' => null,             'requirement_type' => null],
                        ['status_slug' => 'visite',     'title' => 'Préparer la visite',        'due_days' => 2, 'priority' => 0, 'description' => '', 'auto_complete_on' => 'visit_completed',             'requirement_type' => null],
                        ['status_slug' => 'engagement', 'title' => 'Demander les pièces au candidat',      'due_days' => 5, 'priority' => 1, 'description' => 'Pièces justificatives', 'auto_complete_on' => 'demande_pieces_sent',             'requirement_type' => null],
                    ],
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => [
                        ['from_slug' => 'contact',    'to_slug' => 'visite',     'conditions' => ['visit_scheduled'],          'requirement_type' => null],
                        ['from_slug' => 'visite',     'to_slug' => 'engagement', 'conditions' => ['visit_completed'],          'requirement_type' => null],
                        // Sprint 2026-05-22 - Triggers won manquants en standard
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['acte_authentique_signed'],  'requirement_type' => 2],
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['bail_signed'],              'requirement_type' => 4],
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['bail_signed'],              'requirement_type' => 3],
                    ],
                    'maximal'  => [
                        ['from_slug' => 'contact',    'to_slug' => 'visite',     'conditions' => ['visit_scheduled'],          'requirement_type' => null],
                        ['from_slug' => 'visite',     'to_slug' => 'engagement', 'conditions' => ['visit_completed'],          'requirement_type' => null],
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['acte_authentique_signed'],  'requirement_type' => 2],
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['bail_signed'],              'requirement_type' => 4],
                        ['from_slug' => 'engagement', 'to_slug' => 'conclu',     'conditions' => ['bail_signed'],              'requirement_type' => 3],
                    ],
                ],
            ],
        ],

        // ============== INDÉPENDANT (Carte T propre, registre Hoguet) ==============
        'independant' => [
            'vente' => [
                'statuses' => $STATUSES_VENTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_VENTE_STANDARD, 0, 3),
                    'standard' => $TASKS_VENTE_STANDARD,
                    'maximal'  => array_merge($TASKS_VENTE_STANDARD, [
                        ['status_slug' => 'contact',     'title' => 'Relance si pas de réponse J+3',      'due_days' => 3, 'priority' => 1, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'estimation',  'title' => 'Préparer comparables détaillés',     'due_days' => 1, 'priority' => 0, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'avis_valeur', 'title' => 'Relance acceptation avis de valeur', 'due_days' => 7, 'priority' => 1, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'mandat',      'title' => 'Reporting hebdo vendeur',            'due_days' => 7, 'priority' => 0, 'description' => 'Stats annonces + leads', 'auto_complete_on' => null],
                        ['status_slug' => 'compromis',   'title' => 'Suivi SRU J+10',                     'due_days' => 10,'priority' => 2, 'description' => 'Vérifier rétractation',   'auto_complete_on' => null],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [
                        ['from_slug' => 'contact',    'to_slug' => 'estimation', 'conditions' => ['estimation_created'], 'requirement_type' => null],
                    ],
                    'standard' => $TRIGGERS_VENTE_STANDARD,
                    'maximal'  => array_merge($TRIGGERS_VENTE_STANDARD, [
                        ['from_slug' => 'estimation', 'to_slug' => 'mandat', 'conditions' => ['mandat_signed'], 'requirement_type' => 2],
                        ['from_slug' => 'mandat',     'to_slug' => 'compromis', 'conditions' => ['offer_accepted'], 'requirement_type' => null],
                    ]),
                ],
            ],
            'location' => [
                'statuses' => $STATUSES_LOCATION_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_LOCATION_STANDARD, 0, 3),
                    'standard' => $TASKS_LOCATION_STANDARD,
                    'maximal'  => array_merge($TASKS_LOCATION_STANDARD, [
                        ['status_slug' => 'contact', 'title' => 'Relance J+3', 'due_days' => 3, 'priority' => 1, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'dossier', 'title' => 'Relance dossier incomplet J+5', 'due_days' => 5, 'priority' => 2, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'bail',    'title' => 'Convoquer EDL entrée', 'due_days' => 3, 'priority' => 1, 'description' => '', 'auto_complete_on' => null],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_LOCATION_STANDARD,
                    'maximal'  => array_merge($TRIGGERS_LOCATION_STANDARD, [
                        ['from_slug' => 'visite',  'to_slug' => 'dossier', 'conditions' => ['visit_completed','contact_selected'], 'requirement_type' => null],
                    ]),
                ],
            ],
            // Preset HYBRIDE 7 statuts (Mandat/Dossier + Compromis/Bail) - tâches/triggers différenciés par requirement_type
            'vente_location' => [
                'statuses' => $STATUSES_MIXTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_MIXTE_STANDARD, 0, 6),
                    'standard' => $TASKS_MIXTE_STANDARD,
                    'maximal'  => array_merge($TASKS_MIXTE_STANDARD, [
                        ['status_slug' => 'contact',        'title' => 'Relance J+3 si pas de réponse',  'due_days' => 3, 'priority' => 1, 'description' => '',                'auto_complete_on' => null, 'requirement_type' => null],
                        ['status_slug' => 'mandat_bail',    'title' => 'Reporting hebdo vendeur',         'due_days' => 7, 'priority' => 0, 'description' => 'Stats annonces',  'auto_complete_on' => null, 'requirement_type' => 2],
                        ['status_slug' => 'compromis_bail', 'title' => 'Suivi SRU J+10',                  'due_days' => 10,'priority' => 2, 'description' => 'Vérifier rétractation', 'auto_complete_on' => null, 'requirement_type' => 2],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_MIXTE_STANDARD,
                    'maximal'  => $TRIGGERS_MIXTE_STANDARD,
                ],
            ],
        ],

        // ============== MANDATAIRE_RESEAU (même structure qu'indépendant) ==============
        'mandataire_reseau' => [
            'vente' => [
                'statuses' => $STATUSES_VENTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_VENTE_STANDARD, 0, 3),
                    'standard' => $TASKS_VENTE_STANDARD,
                    'maximal'  => array_merge($TASKS_VENTE_STANDARD, [
                        ['status_slug' => 'mandat', 'title' => 'Reporting hebdo vendeur', 'due_days' => 7, 'priority' => 0, 'description' => '', 'auto_complete_on' => null],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_VENTE_STANDARD,
                    'maximal'  => array_merge($TRIGGERS_VENTE_STANDARD, [
                        ['from_slug' => 'mandat', 'to_slug' => 'compromis', 'conditions' => ['offer_accepted'], 'requirement_type' => null],
                    ]),
                ],
            ],
            'location' => [
                'statuses' => $STATUSES_LOCATION_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_LOCATION_STANDARD, 0, 3),
                    'standard' => $TASKS_LOCATION_STANDARD,
                    'maximal'  => $TASKS_LOCATION_STANDARD,
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_LOCATION_STANDARD,
                    'maximal'  => $TRIGGERS_LOCATION_STANDARD,
                ],
            ],
            // Preset HYBRIDE 7 statuts pour mandataire_reseau
            'vente_location' => [
                'statuses' => $STATUSES_MIXTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_MIXTE_STANDARD, 0, 6),
                    'standard' => $TASKS_MIXTE_STANDARD,
                    'maximal'  => array_merge($TASKS_MIXTE_STANDARD, [
                        ['status_slug' => 'mandat_bail', 'title' => 'Reporting hebdo vendeur', 'due_days' => 7, 'priority' => 0, 'description' => '', 'auto_complete_on' => null, 'requirement_type' => 2],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_MIXTE_STANDARD,
                    'maximal'  => $TRIGGERS_MIXTE_STANDARD,
                ],
            ],
        ],

        // ============== AGENCE_SOCIETE (= indépendant mais branding partagé) ==============
        'agence_societe' => [
            'vente' => [
                'statuses' => $STATUSES_VENTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_VENTE_STANDARD, 0, 3),
                    'standard' => $TASKS_VENTE_STANDARD,
                    'maximal'  => array_merge($TASKS_VENTE_STANDARD, [
                        ['status_slug' => 'contact',    'title' => 'Briefing équipe nouveau lead',  'due_days' => 1, 'priority' => 0, 'description' => '', 'auto_complete_on' => null],
                        ['status_slug' => 'mandat',     'title' => 'Reporting hebdo vendeur',       'due_days' => 7, 'priority' => 0, 'description' => '', 'auto_complete_on' => null],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_VENTE_STANDARD,
                    'maximal'  => array_merge($TRIGGERS_VENTE_STANDARD, [
                        ['from_slug' => 'estimation', 'to_slug' => 'mandat',    'conditions' => ['mandat_signed'],  'requirement_type' => 2],
                        ['from_slug' => 'mandat',     'to_slug' => 'compromis', 'conditions' => ['offer_accepted'], 'requirement_type' => null],
                    ]),
                ],
            ],
            'location' => [
                'statuses' => $STATUSES_LOCATION_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_LOCATION_STANDARD, 0, 3),
                    'standard' => $TASKS_LOCATION_STANDARD,
                    'maximal'  => $TASKS_LOCATION_STANDARD,
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_LOCATION_STANDARD,
                    'maximal'  => $TRIGGERS_LOCATION_STANDARD,
                ],
            ],
            // Preset HYBRIDE 7 statuts pour agence_societe
            'vente_location' => [
                'statuses' => $STATUSES_MIXTE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_MIXTE_STANDARD, 0, 6),
                    'standard' => $TASKS_MIXTE_STANDARD,
                    'maximal'  => array_merge($TASKS_MIXTE_STANDARD, [
                        ['status_slug' => 'contact',     'title' => 'Briefing équipe nouveau lead', 'due_days' => 1, 'priority' => 0, 'description' => '', 'auto_complete_on' => null, 'requirement_type' => null],
                        ['status_slug' => 'mandat_bail', 'title' => 'Reporting hebdo vendeur',      'due_days' => 7, 'priority' => 0, 'description' => '', 'auto_complete_on' => null, 'requirement_type' => 2],
                    ]),
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_MIXTE_STANDARD,
                    'maximal'  => $TRIGGERS_MIXTE_STANDARD,
                ],
            ],
        ],

        // ============== AGENCE_INDIVIDUELLE (alias agence_societe) ==============
        'agence_individuelle' => [
            'vente'    => null,          // résolu en fallback agence_societe par le service
            'location' => null,
            'vente_location' => null,    // résolu en fallback agence_societe par le service
        ],

        // ============== PRESTATAIRE_SERVICES (non-Hoguet, B2B + B2C) ==============
        // Pipeline 7 statuts génériques (Prospect → Réalisé) indépendant du
        // mandate_type. Les 3 clés (vente/location/vente_location) référencent
        // les mêmes blocs car les statuts sont génériques. La différenciation
        // par requirement_type se fait au niveau des tasks et triggers maximal.
        'prestataire_services' => [
            'vente' => [
                'statuses' => $STATUSES_PRESTATAIRE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_PRESTATAIRE_STANDARD, 0, 4),
                    'standard' => $TASKS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TASKS_PRESTATAIRE_MAXIMAL,
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TRIGGERS_PRESTATAIRE_STANDARD,
                ],
            ],
            'location' => [
                'statuses' => $STATUSES_PRESTATAIRE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_PRESTATAIRE_STANDARD, 0, 4),
                    'standard' => $TASKS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TASKS_PRESTATAIRE_MAXIMAL,
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TRIGGERS_PRESTATAIRE_STANDARD,
                ],
            ],
            'vente_location' => [
                'statuses' => $STATUSES_PRESTATAIRE_PRO,
                'tasks_by_level' => [
                    'minimal'  => array_slice($TASKS_PRESTATAIRE_STANDARD, 0, 4),
                    'standard' => $TASKS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TASKS_PRESTATAIRE_MAXIMAL,
                ],
                'triggers_by_level' => [
                    'minimal'  => [],
                    'standard' => $TRIGGERS_PRESTATAIRE_STANDARD,
                    'maximal'  => $TRIGGERS_PRESTATAIRE_STANDARD,
                ],
            ],
        ],

    ],
];
