<?php
/**
 * Routes Web - XPROJECT
 * Fichier complet avec toutes les routes
 */

// Charger explicitement le middleware (fix autoload)
require_once APP_PATH . '/Middleware/AuthMiddleware.php';

use App\Controllers\AuthController;
use App\Controllers\DashboardController;
use App\Controllers\CompanyController;
use App\Controllers\ContactController;
use App\Controllers\AdminController;
use App\Controllers\ProductController;
use App\Controllers\DepartmentController;
use App\Controllers\FamilyController;
use App\Controllers\ItemController;
use App\Controllers\PackController;
use App\Controllers\BrandController;
use App\Controllers\ProductConfigController;
use App\Controllers\AddressBookController;
use App\Controllers\PurchaseOrderController;
use App\Controllers\ProjectController;
use App\Controllers\DealController;
use App\Controllers\ActivityController;
use App\Controllers\SettingsController;
use App\Controllers\TransportController;
use App\Controllers\ShareController;
use App\Controllers\CommercialController;
use App\Controllers\ScanController;
use App\Controllers\PlanningController;
use App\Controllers\AxonautController;
use App\Controllers\BillingEntityController;
use App\Controllers\SignatureController;
use App\Controllers\HelpController;
use App\Controllers\PennylaneController;
use App\Controllers\DepotStockController;
use App\Controllers\MetacamController;
use App\Middleware\AuthMiddleware;

$router = new \App\Core\Router();

// ==========================================
// ROUTES PUBLIQUES (sans auth)
// ==========================================
$router->get('/login', fn($r) => (new AuthController())->showLogin($r));
$router->post('/login', fn($r) => (new AuthController())->login($r));
$router->get('/logout', fn($r) => (new AuthController())->logout($r));

// Mot de passe oublié
$router->get('/forgot-password', fn($r) => (new AuthController())->showForgotPassword($r));
$router->post('/forgot-password', fn($r) => (new AuthController())->forgotPassword($r));

// Reset mot de passe (lien depuis l'email)
$router->get('/reset-password', fn($r) => (new AuthController())->showResetPassword($r));
$router->post('/reset-password', fn($r) => (new AuthController())->resetPassword($r));

// Changement de langue (global, sans auth)
$router->get('/lang/{locale}', function($r, $locale) {
    $supported = ['fr', 'en', 'es', 'de', 'it'];
    if (in_array($locale, $supported)) {
        $_SESSION['locale'] = $locale;
        setcookie('locale', $locale, time() + (365 * 24 * 60 * 60), '/');
    }
    $referer = $_SERVER['HTTP_REFERER'] ?? '/xprojectDemo/public/';
    header('Location: ' . $referer);
    exit;
});

// Routes publiques pour la signature électronique (accessible via token)
$router->get('/signatures/sign/{token}', fn($r, $token) => (new SignatureController())->sign($r, $token));
$router->post('/signatures/save/{token}', fn($r, $token) => (new SignatureController())->saveSignature($r, $token));
$router->get('/signatures/success/{token}', fn($r, $token) => (new SignatureController())->success($r, $token));

// ==========================================
// DASHBOARD
// ==========================================
$router->get('/', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DashboardController())->index($req)));
$router->get('/dashboard', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DashboardController())->index($req)));

// ==========================================
// PLANNING (Gantt)
// ==========================================
$router->get('/planning', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->index($req)));
$router->get('/planning/api/data', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiGetData($req)));
$router->get('/planning/api/conflicts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiGetConflicts($req)));
$router->get('/planning/api/search-products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiSearchProducts($req)));
$router->post('/planning/api/update-dates', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiUpdateDates($req)));
$router->post('/planning/api/swap-units', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiSwapUnits($req)));
$router->post('/planning/api/optimize', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiOptimize($req)));
$router->get('/planning/export', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->export($req)));

// Routes pour le drag & drop des intentions
$router->post('/planning/api/intentions/assign', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiAssignIntention($req)));
$router->post('/planning/api/intentions/{assignmentId}/unassign', fn($r, $assignmentId) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiUnassignIntention($req, $assignmentId)));
$router->post('/planning/api/assignments/{assignmentId}/reassign', fn($r, $assignmentId) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiReassignUnit($req, $assignmentId)));

// Routes pour la sous-location
$router->get('/planning/api/suppliers', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiGetSuppliers($req)));
$router->post('/planning/api/intentions/sublease', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiSetSublease($req)));
$router->post('/planning/api/intentions/{intentionId}/remove-sublease', fn($r, $intentionId) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiRemoveSublease($req, $intentionId)));
$router->post('/planning/api/quantity-sublease', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiQuantitySublease($req)));

// Route pour tout désassigner un produit
$router->post('/planning/api/products/{productId}/unassign-all', fn($r, $productId) => AuthMiddleware::handle($r, fn($req) => (new PlanningController())->apiUnassignAllForProduct($req, $productId)));

// ==========================================
// DEPOT STOCKS (Sous-location)
// ==========================================
$router->get('/depot-stocks', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->index($req)));
$router->get('/depot-stocks/pending', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->pendingOrders($req)));
$router->get('/depot-stocks/reports', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->reports($req)));
$router->get('/depot-stocks/exclusions', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->exclusions($req)));
$router->post('/depot-stocks/exclusions/add', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->addExclusion($req)));
$router->post('/depot-stocks/exclusions/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->deleteExclusion($req, $id)));
$router->get('/depot-stocks/report-config/{supplierId}/{dealId}', fn($r, $supplierId, $dealId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->reportConfig($req, $supplierId, $dealId)));
$router->post('/depot-stocks/report-config/{supplierId}/{dealId}/save', fn($r, $supplierId, $dealId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->saveReportConfig($req, $supplierId, $dealId)));
$router->get('/depot-stocks/coefficients', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->coefficients($req)));
$router->get('/depot-stocks/report/{supplierId}/{dealId}', fn($r, $supplierId, $dealId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->reportDetail($req, $supplierId, $dealId)));
$router->get('/depot-stocks/report/{supplierId}/{dealId}/pdf', fn($r, $supplierId, $dealId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->reportPdf($req, $supplierId, $dealId)));
$router->get('/depot-stocks/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->show($req, $id)));
$router->post('/depot-stocks/{id}/update-grid', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->updateGrid($req, $id)));
// API Depot Stocks
$router->post('/depot-stocks/api/create-po', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->createPurchaseOrder($req)));
$router->get('/depot-stocks/api/deal/{dealId}/units', fn($r, $dealId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->getUnitsForDeal($req, $dealId)));
$router->post('/api/depot/units/{unitId}/exclude-coefficient', fn($r, $unitId) => AuthMiddleware::handle($r, fn($req) => (new DepotStockController())->toggleExcludeCoefficient($req, $unitId)));

// ==========================================
// COMPANIES (Sociétés)
// ==========================================
$router->get('/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->index($req)));
$router->get('/companies/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->create($req)));
$router->get('/companies/create-client', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->createClient($req)));
$router->get('/companies/create-supplier', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->createSupplier($req)));
$router->get('/companies/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiSearch($req)));
$router->post('/companies/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->store($req)));
$router->get('/companies/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->show($req, $id)));
$router->get('/companies/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->edit($req, $id)));
$router->post('/companies/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->update($req, $id)));
$router->post('/companies/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->delete($req, $id)));
// API Companies (pour modal)
$router->get('/api/companies/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiSearch($req)));
$router->get('/api/companies/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiGet($req, $id)));
$router->post('/api/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiStore($req)));
$router->post('/api/companies/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiUpdate($req, $id)));
$router->post('/api/companies/{id}/destroy', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CompanyController())->apiDestroy($req, $id)));

// ==========================================
// CONTACTS (liste et CRUD via ContactController avec modal)
// ==========================================
$router->get('/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->index($req)));
$router->get('/contacts/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->create($req)));
$router->post('/contacts/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->store($req)));
$router->get('/contacts/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->edit($req, $id)));
$router->post('/contacts/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->update($req, $id)));
$router->post('/contacts/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->destroy($req, $id)));
// API Contacts (pour modal)
$router->get('/api/contacts/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->apiGet($req, $id)));
$router->post('/api/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->apiStore($req)));
$router->post('/api/contacts/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->apiUpdate($req, $id)));
$router->post('/api/contacts/{id}/destroy', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->apiDestroy($req, $id)));
$router->get('/api/contacts/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->apiSearch($req)));

// ==========================================
// PROJECTS (Projets)
// ==========================================
$router->get('/projects', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->index($req)));
$router->get('/projects/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->create($req)));
$router->post('/projects/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->store($req)));
$router->get('/projects/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->show($req, $id)));
$router->get('/projects/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->edit($req, $id)));
$router->post('/projects/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->update($req, $id)));
// Duplication de projet
$router->get('/projects/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->duplicateForm($req, $id)));
$router->post('/projects/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->duplicate($req, $id)));
$router->get('/api/clients/{id}/contacts', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->getContacts($req, $id)));
$router->post('/api/projects/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->apiUpdateStatus($req, $id)));
// API Modal Projet
$router->get('/api/projects/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->apiGetProject($req, $id)));
$router->post('/api/projects/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->apiStore($req)));
$router->post('/api/projects/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->apiUpdate($req, $id)));
// Suppression projet (admin)
$router->get('/projects/{id}/delete-stats', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->getDeleteStats($req, $id)));
$router->post('/projects/{id}/delete-step', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->deleteProjectStep($req, $id)));
$router->post('/projects/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->deleteProject($req, $id)));
// Demandes de validation de budget
$router->post('/projects/{id}/budget-request', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->requestBudget($req, $id)));
$router->post('/projects/{id}/budget-requests/{requestId}/respond', fn($r, $id, $requestId) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->respondBudget($req, $id, $requestId)));
$router->post('/projects/{id}/set-budget', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProjectController())->setBudget($req, $id)));

// ==========================================
// DEALS (Affaires)
// ==========================================
$router->get('/deals', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DealController())->index($req)));
$router->get('/deals/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DealController())->create($req)));
$router->post('/deals/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DealController())->store($req)));
$router->get('/deals/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->show($req, $id)));
$router->get('/deals/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->edit($req, $id)));
$router->post('/deals/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->update($req, $id)));
$router->post('/deals/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->delete($req, $id)));
$router->post('/deals/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->updateStatus($req, $id)));
$router->post('/deals/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->duplicate($req, $id)));
$router->post('/deals/{id}/assign-units', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->assignUnitsApi($req, $id)));
$router->post('/deals/unassign-unit/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->unassignUnitApi($req, $id)));
$router->post('/deals/{id}/unassign-all', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->unassignAllUnitsApi($req, $id)));
$router->get('/deals/{id}/units-content', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->getUnitsContentApi($req, $id)));
$router->post('/deals/{id}/quick-update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->quickUpdateDeal($req, $id)));
$router->post('/deals/{id}/distribute-discount', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->distributeDiscount($req, $id)));
$router->post('/deals/{id}/reset-discounts', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->resetDiscounts($req, $id)));
$router->post('/deals/{id}/check-discount', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->checkDiscount($req, $id)));

// Routes items des deals - IMPORTANT: reorder AVANT les routes avec {itemId}
$router->post('/deals/{id}/items/reorder', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->reorderItems($req, $id)));
$router->post('/deals/{id}/items/add', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->addItem($req, $id)));
$router->post('/deals/{id}/items', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->addItem($req, $id)));
$router->get('/deals/{id}/scans', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->getScans($req, $id)));
$router->post('/deals/{id}/items/{itemId}', fn($r, $id, $itemId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->updateItem($req, $id, $itemId)));
$router->post('/deals/{id}/items/{itemId}/delete', fn($r, $id, $itemId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->deleteItem($req, $id, $itemId)));
$router->post('/deals/{id}/items/{itemId}/rename', fn($r, $id, $itemId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->renameItem($req, $id, $itemId)));
$router->post('/deals/{id}/items/{itemId}/quick', fn($r, $id, $itemId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->quickUpdateItem($req, $id, $itemId)));
$router->post('/deals/{id}/items/{itemId}/toggle-collapse', fn($r, $id, $itemId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->toggleCollapse($req, $id, $itemId)));
$router->post('/deals/{id}/items/toggle-collapse-all', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->toggleCollapseAll($req, $id)));

// Routes sections des deals
$router->post('/deals/{id}/sections', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->addSection($req, $id)));
$router->post('/deals/{id}/sections/{sectionId}/delete', fn($r, $id, $sectionId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->deleteSection($req, $id, $sectionId)));

// Route BC automatique pour stock en dépôt
$router->post('/deals/{id}/create-depot-po', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->createDepotPurchaseOrder($req, $id)));

// Routes impression des deals (PDF)
$router->get('/deals/{id}/print/quote', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->quote($req, $id)));
$router->get('/deals/{id}/print/picking', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->picking($req, $id)));
$router->get('/deals/{id}/print/prep-global', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->prepGlobal($req, $id)));
$router->get('/deals/{id}/print/prep-internal', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->prepInternal($req, $id)));
$router->get('/deals/{id}/print/prep-subloc', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->prepSubloc($req, $id)));
$router->get('/deals/{id}/print/prep-subloc-list', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->prepSublocList($req, $id)));
$router->get('/deals/{id}/print/delivery', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->delivery($req, $id)));
$router->get('/deals/{id}/print/proforma', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\DealPrintController())->proforma($req, $id)));

// Routes SCAN des deals (codes-barres)
$router->get('/deals/{id}/scan', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->index($req, $id)));
$router->post('/deals/{id}/scan/quick', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->quickScan($req, $id)));
$router->post('/deals/{id}/scan/lookup', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->lookup($req, $id)));
$router->post('/deals/{id}/scan/assign', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->assign($req, $id)));
$router->get('/deals/{id}/scan/list', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->listAssigned($req, $id)));
$router->post('/deals/{id}/scan/{assignmentId}/out', fn($r, $id, $assignmentId) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->markOut($req, $id, $assignmentId)));
$router->post('/deals/{id}/scan/{assignmentId}/returned', fn($r, $id, $assignmentId) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->markReturned($req, $id, $assignmentId)));
$router->post('/deals/{id}/scan/{assignmentId}/cancel', fn($r, $id, $assignmentId) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->cancel($req, $id, $assignmentId)));

// Routes SCAN GLOBAL (page accueil avec tiles)
$router->get('/scan', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->home($req)));
$router->get('/scan/departure', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->departureIndex($req)));
$router->get('/scan/return', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->returnIndex($req)));
$router->get('/scan/tracking', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->trackingIndex($req)));
$router->post('/scan/return/lookup', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->returnLookup($req)));
$router->post('/scan/return/confirm', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->returnConfirm($req)));
$router->post('/scan/return/batch', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->returnBatch($req)));
$router->post('/scan/checkout', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->checkout($req)));
$router->post('/scan/checkin', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ScanController())->checkin($req)));

// ==========================================
// INVOICES (Factures)
// ==========================================
$router->get('/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->index($req)));
$router->get('/invoices/export-excel', fn($r) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->exportExcel($req)));
$router->get('/invoices/export-pdf', fn($r) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->exportPdf($req)));
$router->get('/invoices/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->create($req)));
$router->post('/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->store($req)));
$router->get('/invoices/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->show($req, $id)));
$router->get('/invoices/{id}/pdf', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->pdf($req, $id)));
$router->get('/invoices/{id}/facturx', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->facturx($req, $id)));
$router->post('/invoices/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->updateStatus($req, $id)));
$router->post('/invoices/{id}/payments', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->addPayment($req, $id)));
$router->post('/invoices/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new \App\Controllers\InvoiceController())->delete($req, $id)));

// ==========================================
// COMMERCIAL (Suivi commercial / CRM)
// ==========================================
// API routes en premier (pas de conflit avec {id})
$router->get('/api/commercial/gantt-projects', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->apiGanttProjectsData($req)));
$router->get('/api/commercial/gantt-projects/export', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->exportGanttProjects($req)));
// Pages Commercial
$router->get('/commercial', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->index($req)));
$router->get('/commercial/budget-requests', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->budgetRequests($req)));
$router->get('/commercial/kanban', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->kanban($req)));
$router->get('/commercial/list', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->list($req)));
$router->get('/commercial/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->create($req)));
$router->post('/commercial/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->store($req)));
$router->get('/commercial/gantt-projects', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->ganttProjects($req)));
$router->get('/commercial/kanban-deals', fn($r) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->kanbanDeals($req)));
// Routes avec {id}
$router->get('/commercial/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->show($req, $id)));
$router->get('/commercial/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->edit($req, $id)));
$router->post('/commercial/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->update($req, $id)));
$router->post('/commercial/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->updateStatus($req, $id)));
$router->get('/commercial/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new CommercialController())->delete($req, $id)));

// ==========================================
// ACTIVITIES
// ==========================================
$router->get('/activities', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->index($req)));
$router->post('/activities/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->store($req)));
$router->post('/activities/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->update($req, $id)));
$router->post('/activities/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->delete($req, $id)));

// ==========================================
// SIGNATURES ÉLECTRONIQUES
// ==========================================
$router->get('/signatures', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->index($req)));
$router->get('/signatures/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->create($req)));
$router->post('/signatures/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->store($req)));
$router->get('/signatures/{id}/show', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->show($req, $id)));
$router->post('/signatures/{id}/cancel', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->cancel($req, $id)));
$router->post('/signatures/{id}/resend', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->resend($req, $id)));
$router->get('/signatures/{id}/image', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->getSignatureImage($req, $id)));
$router->get('/signatures/{id}/pdf', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->getSignedPdf($req, $id)));
$router->get('/signatures/{id}/download', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new SignatureController())->download($req, $id)));

// ==========================================
// PRODUCTS (Produits)
// ==========================================
// Products - Page d'accueil
$router->get('/products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductController())->index($req)));

// Products - Configuration
$router->get('/products/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->index($req)));

// Config - Locations
$router->get('/products/config/locations', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->locations($req)));
$router->get('/products/config/locations/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createLocation($req)));
$router->post('/products/config/locations', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeLocation($req)));
$router->get('/products/config/locations/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editLocation($req, $id)));
$router->post('/products/config/locations/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateLocation($req, $id)));
$router->post('/products/config/locations/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyLocation($req, $id)));

// Config - Conditions (états)
$router->get('/products/config/conditions', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->conditions($req)));
$router->get('/products/config/conditions/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createCondition($req)));
$router->post('/products/config/conditions', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeCondition($req)));
$router->get('/products/config/conditions/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editCondition($req, $id)));
$router->post('/products/config/conditions/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateCondition($req, $id)));
$router->post('/products/config/conditions/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyCondition($req, $id)));

// Config - Statuses
$router->get('/products/config/statuses', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->statuses($req)));
$router->get('/products/config/statuses/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createStatus($req)));
$router->post('/products/config/statuses', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeStatus($req)));
$router->get('/products/config/statuses/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editStatus($req, $id)));
$router->post('/products/config/statuses/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateStatus($req, $id)));
$router->post('/products/config/statuses/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyStatus($req, $id)));

// Config - Grids (grilles tarifaires)
$router->get('/products/config/grids', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->grids($req)));
$router->get('/products/config/grids/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createGrid($req)));
$router->post('/products/config/grids', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeGrid($req)));
$router->get('/products/config/grids/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editGrid($req, $id)));
$router->post('/products/config/grids/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateGrid($req, $id)));
$router->post('/products/config/grids/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyGrid($req, $id)));

// Config - Units (unités de facturation)
$router->get('/products/config/units', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->units($req)));
$router->get('/products/config/units/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createUnit($req)));
$router->post('/products/config/units', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeUnit($req)));
$router->get('/products/config/units/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editUnit($req, $id)));
$router->post('/products/config/units/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateUnit($req, $id)));
$router->post('/products/config/units/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyUnit($req, $id)));

// Config - Parameter Groups
$router->get('/products/config/param-groups', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->paramGroups($req)));
$router->get('/products/config/param-groups/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createParamGroup($req)));
$router->post('/products/config/param-groups', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeParamGroup($req)));
$router->get('/products/config/param-groups/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editParamGroup($req, $id)));
$router->post('/products/config/param-groups/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateParamGroup($req, $id)));
$router->post('/products/config/param-groups/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyParamGroup($req, $id)));

// Config - Parameters
$router->get('/products/config/params', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->params($req)));
$router->get('/products/config/params/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createParam($req)));
$router->post('/products/config/params', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeParam($req)));
$router->get('/products/config/params/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editParam($req, $id)));
$router->post('/products/config/params/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateParam($req, $id)));
$router->post('/products/config/params/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyParam($req, $id)));

// Config - Analytical families
$router->get('/products/config/analytical', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->analyticalFamilies($req)));
$router->get('/products/config/analytical/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->createAnalytical($req)));
$router->post('/products/config/analytical', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->storeAnalytical($req)));
$router->get('/products/config/analytical/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->editAnalytical($req, $id)));
$router->post('/products/config/analytical/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->updateAnalytical($req, $id)));
$router->post('/products/config/analytical/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->destroyAnalytical($req, $id)));

// Products - Sous-modules
$router->get('/products/items', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->index($req)));

// Ajout par IA - DOIT ETRE AVANT les routes avec {id}
$router->get('/products/items/ai-create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->aiCreate($req)));
$router->post('/api/products/ai-analyze', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->aiAnalyze($req)));
$router->post('/api/products/ai-save', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->aiSave($req)));
$router->post('/api/products/suggest-specs', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->suggestSpecs($req)));
$router->get('/products/families', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->index($req)));
$router->get('/products/departments', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->index($req)));
$router->get('/products/packs', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->index($req)));
$router->get('/products/brands', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->index($req)));
$router->get('/products/history', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->index($req)));
$router->get('/products/history/export', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->exportCsv($req)));
$router->get('/products/history/{productId}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ActivityController())->productHistory($req, $id)));

// Brands CRUD
$router->get('/products/brands/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->create($req)));
$router->post('/products/brands', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->store($req)));
$router->get('/products/brands/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->edit($req, $id)));
$router->post('/products/brands/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->update($req, $id)));
$router->post('/products/brands/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->destroy($req, $id)));

// Items CRUD
$router->get('/products/items/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->create($req)));
$router->post('/products/items', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->store($req)));
$router->get('/products/items/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->edit($req, $id)));
$router->get('/products/items/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->duplicate($req, $id)));
$router->post('/products/items/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->duplicate($req, $id)));
$router->post('/products/items/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->destroy($req, $id)));
$router->post('/products/items/{id}/images/{imgId}/delete', fn($r, $id, $imgId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->deleteImage($req, $id, $imgId)));
$router->post('/products/items/{id}/images/{imgId}/primary', fn($r, $id, $imgId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->setPrimaryImage($req, $id, $imgId)));

// Items - Actions inline AJAX (AVANT les redirections)
$router->post('/products/items/{id}/toggle-planning', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->togglePlanning($req, $id)));
$router->post('/products/items/{id}/update-family', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->updateFamily($req, $id)));

// Redirections pour les onglets (units, suppliers, specs) - AVANT la route {id}
$router->get('/products/items/{id}/units', fn($r, $id) => Response::redirect("/xprojectDemo/public/products/items/$id#units"));
$router->get('/products/items/{id}/suppliers', fn($r, $id) => Response::redirect("/xprojectDemo/public/products/items/$id#suppliers"));
$router->get('/products/items/{id}/specs', fn($r, $id) => Response::redirect("/xprojectDemo/public/products/items/$id#specs"));

// Items - Units (exemplaires)
$router->post('/products/items/{id}/units', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->storeUnit($req, $id)));
$router->get('/products/items/{id}/units/{unitId}/reactivate', fn($r, $id, $unitId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->reactivateUnit($req, $id, $unitId)));
$router->post('/products/items/{id}/units/{unitId}', fn($r, $id, $unitId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->updateUnit($req, $id, $unitId)));
$router->post('/products/items/{id}/units/{unitId}/delete', fn($r, $id, $unitId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->destroyUnit($req, $id, $unitId)));

// Items - Suppliers (fournisseurs)
$router->post('/products/items/{id}/suppliers', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->storeSupplier($req, $id)));
$router->post('/products/items/{id}/suppliers/{supplierId}/delete', fn($r, $id, $supplierId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->destroySupplier($req, $id, $supplierId)));

// Items - Specs (paramètres techniques)
$router->post('/products/items/{id}/specs', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->storeSpec($req, $id)));
$router->post('/products/items/{id}/specs/{specId}/delete', fn($r, $id, $specId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->destroySpec($req, $id, $specId)));
$router->post('/api/products/{id}/specs/{specId}', fn($r, $id, $specId) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->updateSpecInline($req, $id, $specId)));

// API Familles hiérarchie
$router->get('/api/families-hierarchy', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->getFamiliesHierarchy($req)));

// Historique exemplaires
$router->get('/api/units/{id}/history', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->getUnitHistory($req, $id)));
$router->get('/products/units/{id}/history', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->unitHistoryPage($req, $id)));

$router->get('/products/items/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->show($req, $id)));
$router->post('/products/items/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->update($req, $id)));

// Packs CRUD
$router->get('/products/packs/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->create($req)));
$router->get('/products/packs/export-pdf', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->exportPdf($req)));
$router->post('/products/packs', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->store($req)));
$router->get('/products/packs/{id}/duplicate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->duplicate($req, $id)));
$router->post('/products/packs/{id}/update-name', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->updateName($req, $id)));
$router->post('/products/packs/{id}/update-family', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->updateFamily($req, $id)));
$router->get('/products/packs/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->edit($req, $id)));
$router->get('/products/packs/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->edit($req, $id)));
$router->post('/products/packs/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->update($req, $id)));
$router->post('/products/packs/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->destroy($req, $id)));

// Families CRUD
$router->get('/products/families/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->create($req)));
$router->post('/products/families', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->store($req)));
$router->post('/products/families/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->reorder($req)));
$router->get('/products/families/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->edit($req, $id)));
$router->post('/products/families/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->update($req, $id)));
$router->post('/products/families/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->destroy($req, $id)));

// Departments CRUD
$router->get('/products/departments/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->create($req)));
$router->post('/products/departments', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->store($req)));
$router->post('/products/departments/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->reorder($req)));
$router->get('/products/departments/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->edit($req, $id)));
$router->post('/products/departments/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->update($req, $id)));
$router->post('/products/departments/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->destroy($req, $id)));

// ==========================================
// DEPARTMENTS (Rayons)
// ==========================================
$router->get('/departments', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->index($req)));
$router->get('/departments/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->create($req)));
$router->post('/departments/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->store($req)));
$router->post('/departments/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->reorder($req)));
$router->get('/departments/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->show($req, $id)));
$router->get('/departments/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->edit($req, $id)));
$router->post('/departments/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->update($req, $id)));
$router->post('/departments/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DepartmentController())->delete($req, $id)));

// ==========================================
// FAMILIES (Familles)
// ==========================================
$router->get('/families', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->index($req)));
$router->get('/families/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->create($req)));
$router->post('/families/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->store($req)));
$router->post('/families/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->reorder($req)));
$router->get('/families/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->show($req, $id)));
$router->get('/families/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->edit($req, $id)));
$router->post('/families/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->update($req, $id)));
$router->post('/families/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new FamilyController())->delete($req, $id)));

// ==========================================
// ITEMS (Articles)
// ==========================================
$router->get('/items', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->index($req)));
$router->get('/items/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->create($req)));
$router->post('/items/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->store($req)));
$router->get('/items/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->show($req, $id)));
$router->get('/items/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->edit($req, $id)));
$router->post('/items/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->update($req, $id)));
$router->post('/items/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->delete($req, $id)));

// ==========================================
// PACKS
// ==========================================
$router->get('/packs', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->index($req)));
$router->get('/packs/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->create($req)));
$router->post('/packs/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PackController())->store($req)));
$router->get('/packs/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->show($req, $id)));
$router->get('/packs/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->edit($req, $id)));
$router->post('/packs/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->update($req, $id)));
$router->post('/packs/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PackController())->delete($req, $id)));

// ==========================================
// BRANDS (Marques)
// ==========================================
$router->get('/brands', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->index($req)));
$router->get('/brands/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->create($req)));
$router->post('/brands/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->store($req)));
$router->get('/brands/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->show($req, $id)));
$router->get('/brands/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->edit($req, $id)));
$router->post('/brands/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->update($req, $id)));
$router->post('/brands/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BrandController())->delete($req, $id)));

// ==========================================
// PRODUCT CONFIG
// ==========================================
$router->get('/product-config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->index($req)));
$router->post('/product-config/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductConfigController())->store($req)));

// ==========================================
// CARNET D'ADRESSES (addressbook)
// ==========================================
$router->get('/addressbook', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->index($req)));
$router->get('/addressbook/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->contacts($req)));
$router->get('/addressbook/contacts/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->create($req)));
$router->post('/addressbook/contacts/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->store($req)));
$router->get('/addressbook/contacts/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->edit($req, $id)));
$router->post('/addressbook/contacts/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->update($req, $id)));
$router->post('/addressbook/contacts/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->destroy($req, $id)));
$router->get('/addressbook/categories', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->categories($req)));
$router->get('/addressbook/favorites', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->favorites($req)));
$router->get('/addressbook/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->config($req)));

// API catégories entreprises
$router->post('/api/company-categories', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->storeCategory($req)));
$router->post('/api/company-categories/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->updateCategory($req, $id)));
$router->post('/api/company-categories/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->deleteCategory($req, $id)));
$router->post('/api/company-categories/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->reorderCategories($req)));

// API tags contacts
$router->post('/api/contact-tags', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->storeTag($req)));
$router->post('/api/contact-tags/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->updateTag($req, $id)));
$router->post('/api/contact-tags/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->deleteTag($req, $id)));

// Legacy routes /address-book (compatibilité)
$router->get('/address-book', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->index($req)));
$router->get('/address-book/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->create($req)));
$router->post('/address-book/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->store($req)));
$router->get('/address-book/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->edit($req, $id)));
$router->post('/address-book/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->update($req, $id)));
$router->post('/address-book/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new ContactController())->destroy($req, $id)));

// ==========================================
// PURCHASE ORDERS (Bons de commande)
// ==========================================
$router->get('/purchase-orders', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->index($req)));
$router->get('/purchase-orders/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->create($req)));
$router->post('/purchase-orders/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->store($req)));
$router->get('/purchase-orders/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->edit($req, $id)));
$router->get('/purchase-orders/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->edit($req, $id)));
$router->post('/purchase-orders/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->update($req, $id)));
$router->post('/purchase-orders/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->delete($req, $id)));

// ==========================================
// ACHATS (purchases)
// ==========================================
$router->get('/purchases', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->index($req)));
$router->get('/purchases/orders', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->list($req)));
$router->get('/purchases/orders/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->create($req)));
$router->post('/purchases/orders/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->store($req)));
$router->post('/purchases/orders/send-email', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->sendEmail($req)));
$router->get('/purchases/orders/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->edit($req, $id)));
$router->get('/purchases/orders/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->edit($req, $id)));
$router->post('/purchases/orders/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->update($req, $id)));
$router->post('/purchases/orders/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->destroy($req, $id)));
$router->post('/purchases/orders/{id}/stop', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->apiSaveStop($req, $id)));
$router->get('/purchases/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->config($req)));

// API Bons de commande
$router->post('/api/purchases/orders/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->updateStatus($req, $id)));
$router->delete('/api/purchases/orders/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->apiDelete($req, $id)));
$router->get('/api/purchases/orders/{id}/totals', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->getTotals($req, $id)));
$router->post('/api/purchases/orders/{id}/lines', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->addLine($req, $id)));
$router->post('/api/purchases/orders/{id}/lines/{lineId}', fn($r, $id, $lineId) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->updateLine($req, $id, $lineId)));
$router->post('/api/purchases/orders/{id}/lines/{lineId}/delete', fn($r, $id, $lineId) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->deleteLine($req, $id, $lineId)));
$router->post('/api/purchases/parse-pdf', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->parsePdf($req)));

// API Statuts et Types BC
$router->post('/api/purchases/statuses', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->storeStatus($req)));
$router->post('/api/purchases/statuses/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->updateStatus($req, $id)));
$router->post('/api/purchases/statuses/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->deleteStatus($req, $id)));
$router->post('/api/purchases/types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->storeType($req)));
$router->post('/api/purchases/types/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->updateType($req, $id)));
$router->post('/api/purchases/types/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->deleteType($req, $id)));

// API recherche deals
$router->get('/api/deals/list', fn($r) => AuthMiddleware::handle($r, fn($req) => (new DealController())->apiList($req)));
$router->get('/api/deals/search', fn($r) => AuthMiddleware::handle($r, function($req) {
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $q = $_GET['q'] ?? '';
    if (strlen($q) < 2) return \App\Core\Response::json([]);
    $stmt = $pdo->prepare("SELECT id, name, reference FROM deals WHERE (name LIKE :q1 OR reference LIKE :q2) AND deleted_at IS NULL ORDER BY name LIMIT 20");
    $stmt->execute([':q1' => "%$q%", ':q2' => "%$q%"]);
    return \App\Core\Response::json($stmt->fetchAll(\PDO::FETCH_ASSOC));
}));

// API deals addresses
$router->get('/api/deals/{id}/addresses', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->getAddressesJson($req, $id)));
$router->post('/api/deals/{id}/addresses', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->storeAddress($req, $id)));
$router->post('/api/deals/{id}/addresses/{addressId}', fn($r, $id, $addressId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->updateAddress($req, $id, $addressId)));
$router->post('/api/deals/{id}/addresses/{addressId}/delete', fn($r, $id, $addressId) => AuthMiddleware::handle($r, fn($req) => (new DealController())->deleteAddress($req, $id, $addressId)));

// Départements et familles
$router->post('/api/deals/{id}/departments', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->storeDepartment($req, $id)));
$router->post('/api/deals/{id}/families', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->storeFamily($req, $id)));

// ==========================================
// TRANSPORTS
// ==========================================
// Page d'accueil Transports
$router->get('/transports', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->index($req)));

// Types de véhicules
$router->get('/transports/vehicle-types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->vehicleTypes($req)));
$router->post('/transports/vehicle-types/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->storeVehicleType($req)));
$router->post('/transports/vehicle-types/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->updateVehicleType($req, $id)));
$router->post('/transports/vehicle-types/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->deleteVehicleType($req, $id)));

// Véhicules (Flotte)
$router->get('/transports/vehicles', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->vehicles($req)));
$router->post('/transports/vehicles/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->storeVehicle($req)));
$router->post('/transports/vehicles/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->updateVehicle($req, $id)));
$router->post('/transports/vehicles/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->deleteVehicle($req, $id)));

// Planning et Missions
$router->get('/transports/planning', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->planning($req)));
$router->get('/transports/orphan-stops', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->orphanStops($req)));
$router->post('/api/transports/create-mission-from-date', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiCreateMissionFromDate($req)));
$router->post('/api/transports/create-mission-from-stops', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiCreateMissionFromStops($req)));
$router->post('/api/transports/update-stop-date', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiUpdateStopDate($req)));
$router->get('/transports/missions/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->createMission($req)));
$router->post('/transports/missions/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->storeMission($req)));
$router->get('/transports/missions/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->showMission($req, $id)));
$router->get('/transports/missions/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->editMission($req, $id)));
$router->get('/transports/missions/{id}/pdf', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->missionPdf($req, $id)));
$router->post('/transports/missions/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->updateMission($req, $id)));
$router->post('/transports/missions/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->updateMissionStatus($req, $id)));
$router->post('/api/transports/missions/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiUpdateMissionStatus($req, $id)));
$router->post('/transports/missions/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->deleteMission($req, $id)));

// Chauffeurs
$router->get('/transports/drivers', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->drivers($req)));
$router->post('/transports/drivers/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->storeDriver($req)));
$router->post('/transports/drivers/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->updateDriver($req, $id)));
$router->post('/transports/drivers/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->deleteDriver($req, $id)));

// API Transports
$router->get('/api/transports/vehicles-by-type', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiVehiclesByType($req)));
$router->get('/api/transports/drivers', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiDrivers($req)));
$router->get('/api/transports/vehicle-types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiVehicleTypes($req)));
$router->get('/api/vehicle-types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiVehicleTypes($req)));
$router->post('/api/deals/{id}/add-transport-lines', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->apiAddTransportLines($req, $id)));
$router->post('/api/deals/{id}/contacts', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->apiAddContact($req, $id)));
$router->post('/api/deals/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new DealController())->apiUpdateStatus($req, $id)));
$router->delete('/api/deals/{id}/contacts/{contactId}', fn($r, $id, $cid) => AuthMiddleware::handle($r, fn($req) => (new DealController())->apiRemoveContact($req, $id, $cid)));
$router->post('/api/transports/calculate-cost', fn($r) => AuthMiddleware::handle($r, fn($req) => (new TransportController())->apiCalculateCost($req)));

/// ================================================================
// METACAM - Administration PrepKit
// ================================================================

// Dashboard
$router->get('/metacam', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->index($req)));

// Utilisateurs
$router->get('/metacam/users', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->users($req)));
$router->get('/metacam/users/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->userDetail($req, $id)));
$router->post('/metacam/users/{id}/toggle-active', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->toggleUserActive($req, $id)));
$router->post('/metacam/users/{id}/toggle-admin', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->toggleUserAdmin($req, $id)));

// Loueurs (Rental Companies)
$router->get('/metacam/rental-companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->rentalCompanies($req)));
$router->get('/metacam/rental-companies/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->createRentalCompany($req)));
$router->post('/metacam/rental-companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->storeRentalCompany($req)));
$router->get('/metacam/rental-companies/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->editRentalCompany($req, $id)));
$router->post('/metacam/rental-companies/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->updateRentalCompany($req, $id)));
$router->post('/metacam/rental-companies/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->deleteRentalCompany($req, $id)));
$router->post('/metacam/rental-companies/{id}/moderate', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->moderateRentalCompany($req, $id)));
$router->post('/metacam/rental-companies/{id}/toggle-active', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->toggleRentalActive($req, $id)));

// Types de projet
$router->get('/metacam/project-types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->projectTypes($req)));
$router->post('/metacam/project-types', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->storeProjectType($req)));
$router->post('/metacam/project-types/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->updateProjectType($req, $id)));
$router->post('/metacam/project-types/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->deleteProjectType($req, $id)));
$router->post('/metacam/project-types/reorder', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->reorderProjectTypes($req)));

// Settings
$router->get('/metacam/settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->settings($req)));
$router->post('/metacam/settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->updateSettings($req)));

// Projets (lecture seule)
$router->get('/metacam/projects', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->projects($req)));
$router->get('/metacam/projects/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->projectDetail($req, $id)));

// Documents
$router->get('/metacam/documents', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->documents($req)));
$router->get('/metacam/documents/{id}/view', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->viewDocument($req, $id)));

// Damage Reports (Incidents)
$router->get('/metacam/damage-reports', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->damageReports($req)));
$router->get('/metacam/damage-reports/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->damageReportDetail($req, $id)));
$router->post('/metacam/damage-reports/{id}/status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->updateDamageStatus($req, $id)));
$router->get('/metacam/damage-reports/photos/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->viewDamagePhoto($req, $id)));

// Familles catalogue (sync)
$router->get('/metacam/families', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->families($req)));
$router->post('/metacam/families/{id}/toggle', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->toggleFamily($req, $id)));
$router->post('/metacam/families/toggle-all', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->toggleAllFamilies($req)));

// Synchronisation
$router->get('/metacam/sync', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->sync($req)));
$router->post('/metacam/sync/run', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->runSync($req)));
$router->post('/metacam/sync/step1', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->runSyncStep1($req)));
$router->post('/metacam/sync/step2', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->runSyncStep2($req)));
$router->post('/metacam/sync/step3', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MetacamController())->runSyncStep3($req)));

// ==========================================
// SETTINGS (Paramètres)
// ==========================================
$router->get('/settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->index($req)));
$router->post('/settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->update($req)));

// Settings - Administration (depuis AdminController)
$router->post('/settings/company-info', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->saveCompanyInfo($req)));
$router->post('/settings/company-info-2', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->saveCompanyInfo2($req)));
$router->post('/settings/legal-texts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->saveLegalTexts($req)));
$router->post('/settings/default-settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->saveDefaultSettings($req)));
$router->post('/settings/accounting', fn($r) => AuthMiddleware::handle($r, fn($req) => (new SettingsController())->saveAccountingSettings($req)));

// ==========================================
// HELP (Centre d'aide)
// ==========================================
$router->get('/help', fn($r) => AuthMiddleware::handle($r, fn($req) => (new HelpController())->index($req)));
$router->get('/help/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new HelpController())->search($req)));

// ==========================================
// SHARE (Partage de documents)
// ==========================================
$router->get('/share/email', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->email($req)));
$router->post('/share/send-email', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->sendEmail($req)));
$router->get('/share/whatsapp', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->whatsapp($req)));
$router->post('/share/send-whatsapp', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->sendWhatsApp($req)));
$router->get('/share/view/{token}', fn($r, $token) => (new ShareController())->view($r, $token));
$router->get('/share/pdf/{token}', fn($r, $token) => (new ShareController())->pdf($r, $token));
$router->post('/share/copy-link', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->copyLink($req)));
$router->get('/share/copy-link', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ShareController())->copyLink($req)));

// ==========================================
// ADMIN
// ==========================================
$router->get('/admin', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->index($req)));
$router->get('/admin/route-stats', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->routeStats($req)));
$router->get('/admin/users', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->users($req)));
$router->get('/admin/users/create', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->createUser($req)));
$router->post('/admin/users/store', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->storeUser($req)));
$router->get('/admin/users/{id}/edit', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->editUser($req, $id)));
$router->post('/admin/users/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->updateUser($req, $id)));
$router->post('/admin/users/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->deleteUser($req, $id)));

// ==========================================
// API ADMIN - RBAC (Utilisateurs)
// ==========================================
$router->get('/api/admin/users', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getUsers($req)));
$router->post('/api/admin/users', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->apiCreateUser($req)));
$router->get('/api/admin/users/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getUser($req, $id)));
$router->post('/api/admin/users/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->apiUpdateUser($req, $id)));
$router->post('/api/admin/users/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->apiDeleteUser($req, $id)));
$router->post('/api/admin/users/{id}/toggle-status', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->toggleUserStatus($req, $id)));

// ==========================================
// API ADMIN - RBAC (Rôles)
// ==========================================
$router->get('/api/admin/roles', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getRoles($req)));
$router->post('/api/admin/roles', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->createRole($req)));
$router->get('/api/admin/roles/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getRole($req, $id)));
$router->post('/api/admin/roles/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->updateRole($req, $id)));
$router->post('/api/admin/roles/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->deleteRole($req, $id)));

// ==========================================
// API ADMIN - RBAC (Permissions)
// ==========================================
$router->get('/api/admin/permissions', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getPermissions($req)));
$router->get('/api/admin/permissions/{module}', fn($r, $module) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getPermissionsByModule($req, $module)));
$router->get('/api/permissions/check', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->checkPermission($req)));
$router->get('/api/permissions/mine', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getMyPermissions($req)));

// API Admin - Intelligence Artificielle
$router->get('/api/admin/ai/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getAIConfig($req)));
$router->post('/api/admin/ai/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->saveAIConfig($req)));
$router->get('/api/admin/ai/prompts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getAIPrompts($req)));
$router->get('/api/admin/ai/prompts/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getAIPrompt($req, $id)));
$router->post('/api/admin/ai/prompts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->createAIPrompt($req)));
$router->post('/api/admin/ai/prompts/{id}/update', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->updateAIPrompt($req, $id)));
$router->post('/api/admin/ai/prompts/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->deleteAIPrompt($req, $id)));

// Mail configuration & logs
$router->get('/api/admin/mail/logs', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getMailLogs($req)));
$router->post('/api/admin/mail/test', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->sendTestMail($req)));
$router->get('/api/admin/mail/history', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AdminController())->getEmailHistory($req)));

// ==========================================
// BILLING ENTITIES (Entités de facturation)
// ==========================================
$router->get('/billing-entities', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->index($req)));
$router->get('/billing-entities/list', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->list($req)));
$router->post('/billing-entities/upload-logo', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->uploadLogo($req)));
$router->get('/billing-entities/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->get($req, $id)));
$router->post('/billing-entities', fn($r) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->store($req)));
$router->post('/billing-entities/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->update($req, $id)));
$router->post('/billing-entities/{id}/delete', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->delete($req, $id)));
$router->post('/billing-entities/{id}/default', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new BillingEntityController())->setDefault($req, $id)));

// ==========================================
// AXONAUT (Synchronisation CRM)
// ==========================================
// Page principale Axonaut
$router->get('/axonaut', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->index($req)));
$router->get('/axonaut/settings', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->settings($req)));

// API Axonaut - Configuration
$router->get('/api/axonaut/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getConfig($req)));
$router->post('/api/axonaut/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->saveConfig($req)));
$router->post('/api/axonaut/disconnect', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->disconnect($req)));
$router->get('/api/axonaut/test-entity', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testEntityConnection($req)));

// API Axonaut - Test & Stats
$router->get('/api/axonaut/test', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testConnection($req)));
$router->get('/api/axonaut/test-invoice', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testInvoiceEndpoint($req)));
$router->get('/api/axonaut/test-products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testProductStructure($req)));
$router->get('/api/axonaut/test-contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testContactStructure($req)));
$router->get('/api/axonaut/test-companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testCompanyStructure($req)));
$router->get('/api/axonaut/test-quotations', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->testQuotationStructure($req)));
$router->get('/api/axonaut/fix-contact', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->fixContactCompany($req)));
$router->get('/api/axonaut/company-employees', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->listCompanyEmployees($req)));
$router->get('/api/axonaut/stats', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getStats($req)));

// API Axonaut - Liste des entités
$router->get('/api/axonaut/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getCompanies($req)));
$router->get('/api/axonaut/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getContacts($req)));
$router->get('/api/axonaut/products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getProducts($req)));
$router->get('/api/axonaut/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getInvoices($req)));
$router->get('/api/axonaut/quotations', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->getQuotations($req)));

// API Axonaut - Export (Push vers Axonaut)
$router->post('/api/axonaut/export/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportCompanies($req)));
$router->post('/api/axonaut/export/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportContacts($req)));
$router->post('/api/axonaut/export/products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportProducts($req)));
$router->post('/api/axonaut/export/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportInvoices($req)));
$router->post('/api/axonaut/export/quotations', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportQuotations($req)));

// API Axonaut - Preview et export avec modification
$router->get('/api/axonaut/invoices/{id}/preview', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->previewInvoice($req, $id)));
$router->post('/api/axonaut/invoices/{id}/export', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->exportInvoiceWithData($req, $id)));

// API Axonaut - Import (Pull depuis Axonaut)
$router->post('/api/axonaut/import/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->importCompanies($req)));

// API Axonaut - Suppression dans Axonaut
$router->post('/api/axonaut/delete/companies', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->deleteCompanies($req)));
$router->post('/api/axonaut/delete/contacts', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->deleteContacts($req)));
$router->post('/api/axonaut/delete/products', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->deleteProducts($req)));
$router->post('/api/axonaut/delete/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->deleteInvoices($req)));

// Debug: vérification synchro
$router->get('/api/axonaut/verify-sync', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AxonautController())->debugVerifySync($req)));

// ==========================================
// PENNYLANE (Comptabilité)
// ==========================================
$router->get('/pennylane', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->index($req)));
$router->post('/pennylane/config', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->saveConfig($req)));
$router->post('/pennylane/disconnect', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->disconnect($req)));
$router->get('/pennylane/test', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->testConnection($req)));
$router->post('/pennylane/export/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->exportInvoice($req, $id)));
$router->post('/pennylane/export-batch', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->exportBatch($req)));

// API Pennylane (pour l'onglet dans InvoiceController)
$router->get('/api/pennylane/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->apiInvoices($req)));
$router->get('/api/pennylane/invoices/{id}/preview', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->apiPreview($req, $id)));
$router->post('/api/pennylane/invoices/{id}/export', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->apiExportInvoice($req, $id)));
$router->post('/api/pennylane/export/invoices', fn($r) => AuthMiddleware::handle($r, fn($req) => (new PennylaneController())->exportBatch($req)));

// ==========================================
// API GÉNÉRALES (routes non définies ailleurs)
// ==========================================
// Note: /api/companies/search, /api/companies/{id}, /companies/search, /api/contacts/search
// sont déjà définies dans leurs sections respectives (COMPANIES, CONTACTS)
$router->get('/companies/{id}/contacts/json', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new PurchaseOrderController())->apiGetCompanyContacts($req, $id)));
$router->post('/api/contacts/ai-create', fn($r) => AuthMiddleware::handle($r, fn($req) => apiCreateContactWithAI($req)));
$router->post('/api/contacts/ai-create-for-company', fn($r) => AuthMiddleware::handle($r, fn($req) => apiCreateContactWithAIForCompany($req)));
$router->get('/api/products/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ProductController())->apiSearch($req)));
$router->get('/api/items/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new ItemController())->apiSearch($req)));
$router->get('/api/addresses/search', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->apiSearch($req)));
$router->get('/api/addresses/favorites', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->apiFavorites($req)));
$router->post('/api/addresses/parse', fn($r) => AuthMiddleware::handle($r, fn($req) => (new AddressBookController())->apiParse($req)));

// API User Favorites
$router->get('/api/user/favorites', fn($r) => AuthMiddleware::handle($r, fn($req) => apiGetFavorites($req)));
$router->post('/api/user/favorites/toggle', fn($r) => AuthMiddleware::handle($r, fn($req) => apiToggleFavorite($req)));
$router->get('/api/user/favorites/check/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => apiCheckFavorite($req, $id)));

// API Route Calculator (OpenRouteService)
$router->post('/api/route/calculate', fn($r) => AuthMiddleware::handle($r, fn($req) => apiCalculateRoute($req)));

// API AI - Parse Address et Calculate Distance
$router->post('/api/ai/parse-address', fn($r) => AuthMiddleware::handle($r, fn($req) => apiParseAddress($req)));
$router->post('/api/ai/calculate-distance', fn($r) => AuthMiddleware::handle($r, fn($req) => apiCalculateDistance($req)));

// ==========================================
// API MOBILE (Application iOS/Android)
// ==========================================
use App\Controllers\MobileApiController;

// Authentification Mobile (pas de middleware pour login)
$router->post('/api/mobile/login', fn($r) => (new MobileApiController())->login($r));
$router->get('/api/mobile/auth/check', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->checkAuth($req)));

// Dashboard stats
$router->get('/api/mobile/stats', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->getStats($req)));

// Affaires
$router->get('/api/mobile/deals', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->getDeals($req)));
$router->get('/api/mobile/deals/{id}', fn($r, $id) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->getDeal($req, $id)));

// Reporting
$router->get('/api/mobile/reporting', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->getReporting($req)));

// Entités (pour filtres)
$router->get('/api/mobile/entities', fn($r) => AuthMiddleware::handle($r, fn($req) => (new MobileApiController())->getEntities($req)));

// ==========================================
// DISPATCH
// ==========================================
return $router;

// ==========================================
// FONCTIONS API HELPERS
// ==========================================

/**
 * API: Liste des favoris utilisateur (companies + contacts)
 */
function apiGetFavorites($request) {
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $userId = $_SESSION['user_id'] ?? 0;

    if (!$userId) {
        return \App\Core\Response::json(['companies' => [], 'contacts' => []]);
    }

    try {
        // Entreprises favorites
        $stmtC = $pdo->prepare("
            SELECT c.id, c.name, c.address, c.postal_code, c.city, 'company' AS type
            FROM user_address_favorites f
            JOIN companies c ON f.company_id = c.id
            WHERE f.user_id = ? AND f.company_id IS NOT NULL AND c.deleted_at IS NULL
            ORDER BY c.name
        ");
        $stmtC->execute([$userId]);
        $companies = $stmtC->fetchAll(\PDO::FETCH_ASSOC);

        // Contacts favoris
        $stmtCt = $pdo->prepare("
            SELECT ct.id, CONCAT(ct.first_name, ' ', ct.last_name) AS name, ct.address, ct.postal_code, ct.city, 'contact' AS type
            FROM user_address_favorites f
            JOIN contacts ct ON f.contact_id = ct.id
            WHERE f.user_id = ? AND f.contact_id IS NOT NULL AND ct.deleted_at IS NULL
            ORDER BY ct.last_name, ct.first_name
        ");
        $stmtCt->execute([$userId]);
        $contacts = $stmtCt->fetchAll(\PDO::FETCH_ASSOC);

        return \App\Core\Response::json(['companies' => $companies, 'contacts' => $contacts]);
    } catch (\Exception $e) {
        return \App\Core\Response::json(['error' => $e->getMessage()], 500);
    }
}

/**
 * API: Toggle favori (company ou contact)
 */
function apiToggleFavorite($request) {
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $userId = $_SESSION['user_id'] ?? 0;

    if (!$userId) {
        return \App\Core\Response::json(['error' => 'Non connecté'], 401);
    }

    // Lire les données JSON
    $data = json_decode(file_get_contents('php://input'), true);
    $companyId = $data['company_id'] ?? null;
    $contactId = $data['contact_id'] ?? null;

    if (!$companyId && !$contactId) {
        return \App\Core\Response::json(['error' => 'company_id ou contact_id requis'], 400);
    }

    try {
        if ($companyId) {
            // Favori entreprise
            $check = $pdo->prepare("SELECT id FROM user_address_favorites WHERE user_id = ? AND company_id = ?");
            $check->execute([$userId, $companyId]);
            if ($check->fetch()) {
                $pdo->prepare("DELETE FROM user_address_favorites WHERE user_id = ? AND company_id = ?")->execute([$userId, $companyId]);
                return \App\Core\Response::json(['favorited' => false]);
            } else {
                $pdo->prepare("INSERT INTO user_address_favorites (user_id, company_id) VALUES (?, ?)")->execute([$userId, $companyId]);
                return \App\Core\Response::json(['favorited' => true]);
            }
        } else {
            // Favori contact
            $check = $pdo->prepare("SELECT id FROM user_address_favorites WHERE user_id = ? AND contact_id = ?");
            $check->execute([$userId, $contactId]);
            if ($check->fetch()) {
                $pdo->prepare("DELETE FROM user_address_favorites WHERE user_id = ? AND contact_id = ?")->execute([$userId, $contactId]);
                return \App\Core\Response::json(['favorited' => false]);
            } else {
                $pdo->prepare("INSERT INTO user_address_favorites (user_id, contact_id) VALUES (?, ?)")->execute([$userId, $contactId]);
                return \App\Core\Response::json(['favorited' => true]);
            }
        }
    } catch (\Exception $e) {
        return \App\Core\Response::json(['error' => $e->getMessage()], 500);
    }
}

/**
 * API: Vérifier si un élément est en favori
 */
function apiCheckFavorite($request, $id) {
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $userId = $_SESSION['user_id'] ?? 0;
    $type = $_GET['type'] ?? 'company';

    if (!$userId) {
        return \App\Core\Response::json(['favorited' => false]);
    }

    try {
        if ($type === 'company') {
            $stmt = $pdo->prepare("SELECT id FROM user_address_favorites WHERE user_id = ? AND company_id = ?");
        } else {
            $stmt = $pdo->prepare("SELECT id FROM user_address_favorites WHERE user_id = ? AND contact_id = ?");
        }
        $stmt->execute([$userId, $id]);
        return \App\Core\Response::json(['favorited' => (bool)$stmt->fetch()]);
    } catch (\Exception $e) {
        return \App\Core\Response::json(['favorited' => false]);
    }
}

/**
 * API: Calculer un itinéraire via OpenRouteService
 */
function apiCalculateRoute($request) {
    $data = json_decode(file_get_contents('php://input'), true);
    $coordinates = $data['coordinates'] ?? [];

    if (count($coordinates) < 2) {
        return \App\Core\Response::json(['error' => 'Au moins 2 coordonnées requises'], 400);
    }

    $apiKey = $_ENV['ORS_API_KEY'] ?? getenv('ORS_API_KEY') ?? '';
    if (!$apiKey) {
        return \App\Core\Response::json(['error' => 'Clé API OpenRouteService non configurée'], 500);
    }

    $url = 'https://api.openrouteservice.org/v2/directions/driving-car';
    $payload = json_encode(['coordinates' => $coordinates]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'Authorization: ' . $apiKey,
            'Content-Type: application/json',
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return \App\Core\Response::json(['error' => 'Erreur OpenRouteService', 'details' => $response], $httpCode);
    }

    return \App\Core\Response::json(json_decode($response, true));
}

/**
 * API: Parser une adresse via AI/Geocoding
 */
function apiParseAddress($request) {
    $data = json_decode(file_get_contents('php://input'), true);
    $rawAddress = $data['raw_address'] ?? $data['address'] ?? '';

    if (!$rawAddress) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Adresse requise'], 400);
    }

    // Récupérer la config AI
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $config = [];
    $rows = $pdo->query("SELECT `key`, `value` FROM ai_config")->fetchAll(\PDO::FETCH_ASSOC);
    foreach ($rows as $row) {
        $config[$row['key']] = $row['value'];
    }

    // Récupérer le prompt
    $stmt = $pdo->prepare("SELECT * FROM ai_prompts WHERE `key` = 'address_parse' AND is_active = 1");
    $stmt->execute();
    $prompt = $stmt->fetch(\PDO::FETCH_ASSOC);

    if (!$prompt || empty($config['api_key'])) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Configuration IA manquante'], 500);
    }

    // Préparer le prompt utilisateur
    $userPrompt = str_replace('{{raw_address}}', $rawAddress, $prompt['user_prompt_template']);

    // Appel OpenAI
    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['api_key']
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'model' => $prompt['model'] ?? 'gpt-4o-mini',
            'messages' => [
                ['role' => 'system', 'content' => $prompt['system_prompt']],
                ['role' => 'user', 'content' => $userPrompt]
            ],
            'temperature' => (float)($prompt['temperature'] ?? 0.1),
            'max_tokens' => (int)($prompt['max_tokens'] ?? 300)
        ])
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur API OpenAI'], 500);
    }

    $result = json_decode($response, true);
    $content = $result['choices'][0]['message']['content'] ?? '';

    // Parser le JSON retourné par IA
    $parsed = json_decode($content, true);
    if (!$parsed) {
        $content = preg_replace('/```json\s*|\s*```/', '', $content);
        $parsed = json_decode(trim($content), true);
    }

    if (!$parsed) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Réponse IA invalide'], 500);
    }

    return \App\Core\Response::json([
        'success' => true,
        'data' => [
            'address_line' => trim(($parsed['street_number'] ?? '') . ' ' . ($parsed['street_name'] ?? '')),
            'street_number' => $parsed['street_number'] ?? '',
            'street_name' => $parsed['street_name'] ?? '',
            'postal_code' => $parsed['postal_code'] ?? '',
            'city' => $parsed['city'] ?? '',
            'is_known_place' => $parsed['is_known_place'] ?? false,
            'place_name' => $parsed['place_name'] ?? null
        ]
    ]);
}

/**
 * API: Calculer la distance entre deux adresses
 */
function apiCalculateDistance($request) {
    $data = json_decode(file_get_contents('php://input'), true);
    $fromAddress = $data['from_address'] ?? $data['from'] ?? null;
    $toAddress = $data['to_address'] ?? $data['to'] ?? null;

    if (!$fromAddress || !$toAddress) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Adresses from et to requises'], 400);
    }

    // Récupérer la config AI
    $pdo = \App\Core\Database::getInstance()->getConnection();
    $config = [];
    $rows = $pdo->query("SELECT `key`, `value` FROM ai_config")->fetchAll(\PDO::FETCH_ASSOC);
    foreach ($rows as $row) {
        $config[$row['key']] = $row['value'];
    }

    // Vérifier si on utilise OpenRouteService
    if (!empty($config['ors_enabled']) && $config['ors_enabled'] == '1' && !empty($config['ors_api_key'])) {
        return calculateDistanceWithORS($fromAddress, $toAddress, $config['ors_api_key']);
    }

    // Sinon utiliser IA
    $stmt = $pdo->prepare("SELECT * FROM ai_prompts WHERE `key` = 'distance_calculate' AND is_active = 1");
    $stmt->execute();
    $prompt = $stmt->fetch(\PDO::FETCH_ASSOC);

    if (!$prompt || empty($config['api_key'])) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Configuration IA manquante'], 500);
    }

    $userPrompt = str_replace(
        ['{{from_address}}', '{{to_address}}'],
        [$fromAddress, $toAddress],
        $prompt['user_prompt_template']
    );

    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['api_key']
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'model' => $prompt['model'] ?? 'gpt-4o-mini',
            'messages' => [
                ['role' => 'system', 'content' => $prompt['system_prompt']],
                ['role' => 'user', 'content' => $userPrompt]
            ],
            'temperature' => (float)($prompt['temperature'] ?? 0.2),
            'max_tokens' => (int)($prompt['max_tokens'] ?? 200)
        ])
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur API OpenAI'], 500);
    }

    $result = json_decode($response, true);
    $content = $result['choices'][0]['message']['content'] ?? '';

    $parsed = json_decode($content, true);
    if (!$parsed) {
        $content = preg_replace('/```json\s*|\s*```/', '', $content);
        $parsed = json_decode(trim($content), true);
    }

    if (!$parsed) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Réponse IA invalide'], 500);
    }

    return \App\Core\Response::json([
        'success' => true,
        'data' => [
            'distance_km' => $parsed['distance_km'] ?? 0,
            'duration_minutes' => $parsed['duration_minutes'] ?? 0,
            'duration_text' => $parsed['duration_text'] ?? '',
            'route_summary' => $parsed['route_summary'] ?? ''
        ]
    ]);
}

/**
 * Calcul de distance avec OpenRouteService
 */
function calculateDistanceWithORS($fromAddress, $toAddress, $apiKey) {
    // Geocoder les adresses
    $fromCoords = geocodeWithORS($fromAddress, $apiKey);
    $toCoords = geocodeWithORS($toAddress, $apiKey);

    if (!$fromCoords || !$toCoords) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Impossible de géocoder les adresses'], 400);
    }

    // Appel API directions
    $ch = curl_init('https://api.openrouteservice.org/v2/directions/driving-car');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: ' . $apiKey
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'coordinates' => [
                [$fromCoords['lon'], $fromCoords['lat']],
                [$toCoords['lon'], $toCoords['lat']]
            ]
        ])
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur API ORS'], 500);
    }

    $result = json_decode($response, true);
    $route = $result['routes'][0] ?? null;

    if (!$route) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Aucun itinéraire trouvé'], 404);
    }

    $distanceKm = round($route['summary']['distance'] / 1000, 1);
    $durationMin = round($route['summary']['duration'] / 60);

    $durationText = $durationMin < 60
        ? $durationMin . ' min'
        : floor($durationMin / 60) . 'h' . str_pad($durationMin % 60, 2, '0', STR_PAD_LEFT);

    return \App\Core\Response::json([
        'success' => true,
        'data' => [
            'distance_km' => $distanceKm,
            'duration_minutes' => $durationMin,
            'duration_text' => $durationText,
            'route_summary' => 'Via itinéraire routier'
        ]
    ]);
}

/**
 * Geocoder une adresse avec OpenRouteService
 */
function geocodeWithORS($address, $apiKey) {
    $ch = curl_init('https://api.openrouteservice.org/geocode/search?' . http_build_query([
        'api_key' => $apiKey,
        'text' => $address,
        'boundary.country' => 'FR',
        'size' => 1
    ]));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($ch);
    curl_close($ch);

    $result = json_decode($response, true);
    $feature = $result['features'][0] ?? null;

    if (!$feature) {
        return null;
    }

    return [
        'lon' => $feature['geometry']['coordinates'][0],
        'lat' => $feature['geometry']['coordinates'][1]
    ];
}

/**
 * API: Créer un contact via IA et l'ajouter à un deal
 */
function apiCreateContactWithAI($request) {
    try {
        $data = json_decode(file_get_contents('php://input'), true);
        $rawInput = $data['raw_input'] ?? '';
        $dealId = $data['deal_id'] ?? null;

        if (!$rawInput) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Informations requises'], 400);
        }

        $pdo = \App\Core\Database::getInstance()->getConnection();

        // Récupérer la config AI
        $config = [];
        $rows = $pdo->query("SELECT `key`, `value` FROM ai_config")->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($rows as $row) {
            $config[$row['key']] = $row['value'];
        }

        // Récupérer les jobs existants avec leur département
        $jobsContext = "";
        try {
            $jobsStmt = $pdo->query("
                SELECT cj.name AS job_name, cd.code AS dept_code, cd.name AS dept_name, cd.description AS dept_desc
                FROM contact_jobs cj
                LEFT JOIN contact_departments cd ON cj.department_id = cd.id
                WHERE cj.is_active = 1
                ORDER BY cd.name, cj.name
            ");
            $jobs = $jobsStmt->fetchAll(\PDO::FETCH_ASSOC);
            if (!empty($jobs)) {
                $jobsList = [];
                foreach ($jobs as $job) {
                    $jobsList[] = $job['job_name'] . ' (' . $job['dept_name'] . ')';
                }
                $jobsContext = "Métiers connus: " . implode(', ', $jobsList);
            }
        } catch (\Exception $e) {
            // Tables peuvent ne pas exister
        }

        // Départements disponibles (ENUM de la table contacts)
        $departmentsContext = "Départements valides: image (Image/Caméra), light (Lumière/Électricité), grip (Machinerie), sound (Son), production (Production), direction (Réalisation), art (Direction artistique/Décors), post (Post-production), other (Autre)";

        // Récupérer le prompt pour contact_parse
        $stmt = $pdo->prepare("SELECT * FROM ai_prompts WHERE `key` = 'contact_parse' AND is_active = 1");
        $stmt->execute();
        $prompt = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$prompt || empty($config['api_key'])) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Configuration IA manquante. Créez le prompt "contact_parse" dans l\'administration.'], 500);
        }

        // Préparer le prompt utilisateur avec contexte métiers/départements
        $userPrompt = str_replace('{{raw_input}}', $rawInput, $prompt['user_prompt_template']);
        $userPrompt = str_replace('{{jobs_context}}', $jobsContext, $userPrompt);
        $userPrompt = str_replace('{{departments_context}}', $departmentsContext, $userPrompt);

    // Appel OpenAI
    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['api_key']
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'model' => $prompt['model'] ?? 'gpt-4o-mini',
            'messages' => [
                ['role' => 'system', 'content' => $prompt['system_prompt']],
                ['role' => 'user', 'content' => $userPrompt]
            ],
            'temperature' => (float)($prompt['temperature'] ?? 0.1),
            'max_tokens' => (int)($prompt['max_tokens'] ?? 500)
        ])
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur API OpenAI'], 500);
    }

    $result = json_decode($response, true);
    $content = $result['choices'][0]['message']['content'] ?? '';

    // Parser le JSON retourné par IA
    $parsed = json_decode($content, true);
    if (!$parsed) {
        $content = preg_replace('/```json\s*|\s*```/', '', $content);
        $parsed = json_decode(trim($content), true);
    }

    if (!$parsed) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Réponse IA invalide'], 500);
    }

    $civility = trim($parsed['civility'] ?? '');
    $firstName = trim($parsed['first_name'] ?? '');
    $lastName = trim($parsed['last_name'] ?? '');
    $email = trim($parsed['email'] ?? '');
    $phone = normalizePhoneNumber($parsed['phone'] ?? '');
    $mobile = normalizePhoneNumber($parsed['mobile'] ?? $parsed['phone'] ?? '');
    $jobTitle = trim($parsed['job_title'] ?? $parsed['position'] ?? '');
    $companyName = trim($parsed['company_name'] ?? '');
    $departmentRaw = trim($parsed['department'] ?? '');

    // Normaliser la civilité (M. ou Mme)
    if ($civility) {
        $civilityLower = strtolower($civility);
        if (strpos($civilityLower, 'mme') !== false || strpos($civilityLower, 'madame') !== false || $civilityLower === 'f' || $civilityLower === 'femme') {
            $civility = 'Mme';
        } else {
            $civility = 'M.';
        }
    }

    // Normaliser le département (doit être une valeur ENUM valide)
    $validDepartments = ['image', 'light', 'grip', 'sound', 'production', 'direction', 'art', 'post', 'other'];
    $department = null;
    if ($departmentRaw) {
        $deptLower = strtolower($departmentRaw);
        if (in_array($deptLower, $validDepartments)) {
            $department = $deptLower;
        } else {
            // Essayer de mapper des termes courants
            $deptMappings = [
                'camera' => 'image', 'caméra' => 'image', 'dop' => 'image', 'chef op' => 'image', 'cadreur' => 'image', 'steadicam' => 'image',
                'lumière' => 'light', 'lumiere' => 'light', 'électricien' => 'light', 'electricien' => 'light', 'chef électro' => 'light',
                'machinerie' => 'grip', 'machino' => 'grip', 'machiniste' => 'grip',
                'son' => 'sound', 'ingénieur son' => 'sound', 'perchman' => 'sound', 'mixeur' => 'sound',
                'prod' => 'production', 'producteur' => 'production', 'directeur production' => 'production', 'régisseur' => 'production',
                'réalisateur' => 'direction', 'realisateur' => 'direction', 'assistant réal' => 'direction',
                'décor' => 'art', 'decor' => 'art', 'chef déco' => 'art', 'accessoiriste' => 'art', 'costumier' => 'art',
                'montage' => 'post', 'monteur' => 'post', 'étalonnage' => 'post', 'vfx' => 'post'
            ];
            foreach ($deptMappings as $key => $value) {
                if (strpos($deptLower, $key) !== false) {
                    $department = $value;
                    break;
                }
            }
        }
    }

    if (!$firstName && !$lastName && !$email) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Impossible d\'extraire les informations du contact'], 400);
    }

    // Chercher si le contact existe déjà (par email ou nom+prénom)
    $existingContactId = null;

    if ($email) {
        $stmt = $pdo->prepare("SELECT id FROM contacts WHERE email = ? AND deleted_at IS NULL LIMIT 1");
        $stmt->execute([$email]);
        $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
        if ($existing) {
            $existingContactId = $existing['id'];
        }
    }

    if (!$existingContactId && $firstName && $lastName) {
        $stmt = $pdo->prepare("SELECT id FROM contacts WHERE first_name = ? AND last_name = ? AND deleted_at IS NULL LIMIT 1");
        $stmt->execute([$firstName, $lastName]);
        $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
        if ($existing) {
            $existingContactId = $existing['id'];
        }
    }

    $created = false;
    $contactId = $existingContactId;

    // Déterminer le statut d'emploi (employment_status) - par défaut "intermittent"
    $employmentStatus = 'intermittent'; // Valeurs possibles: employee, intermittent, freelance, auto, retired
    $jobTitleLower = strtolower($jobTitle);
    if (strpos($jobTitleLower, 'salarié') !== false || strpos($jobTitleLower, 'employee') !== false) {
        $employmentStatus = 'employee';
    } elseif (strpos($jobTitleLower, 'freelance') !== false || strpos($jobTitleLower, 'indépendant') !== false) {
        $employmentStatus = 'freelance';
    } elseif (strpos($jobTitleLower, 'auto') !== false || strpos($jobTitleLower, 'micro') !== false) {
        $employmentStatus = 'auto';
    }

    // Si le contact n'existe pas, le créer
    if (!$contactId) {
        // Chercher l'entreprise si fournie
        $companyId = null;
        if ($companyName) {
            $stmt = $pdo->prepare("SELECT id FROM companies WHERE name LIKE ? AND deleted_at IS NULL LIMIT 1");
            $stmt->execute(['%' . $companyName . '%']);
            $company = $stmt->fetch(\PDO::FETCH_ASSOC);
            if ($company) {
                $companyId = $company['id'];
            }
        }

        // Créer le contact avec civility, position, department et employment_status
        $stmt = $pdo->prepare("
            INSERT INTO contacts (civility, first_name, last_name, email, phone, mobile, position, department, employment_status, company_id, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
        ");
        $stmt->execute([
            $civility ?: null,
            $firstName ?: null,
            $lastName ?: null,
            $email ?: null,
            $phone ?: null,
            $mobile ?: null,
            $jobTitle ?: null,
            $department,
            $employmentStatus,
            $companyId
        ]);
        $contactId = $pdo->lastInsertId();
        $created = true;
    }

    // Si un deal_id est fourni, ajouter le contact au deal
    if ($dealId && $contactId) {
        // Vérifier que le contact n'est pas déjà dans le deal
        $stmt = $pdo->prepare("SELECT id FROM deal_contacts WHERE deal_id = ? AND contact_id = ?");
        $stmt->execute([$dealId, $contactId]);
        if (!$stmt->fetch()) {
            $stmt = $pdo->prepare("
                INSERT INTO deal_contacts (deal_id, contact_id, role, sort_order)
                VALUES (?, ?, 'technical', (SELECT COALESCE(MAX(sort_order), 0) + 1 FROM deal_contacts dc WHERE dc.deal_id = ?))
            ");
            $stmt->execute([$dealId, $contactId, $dealId]);
        }
    }

    return \App\Core\Response::json([
        'success' => true,
        'created' => $created,
        'contact_id' => $contactId,
        'data' => [
            'first_name' => $firstName,
            'last_name' => $lastName,
            'email' => $email,
            'phone' => $phone,
            'mobile' => $mobile,
            'job_title' => $jobTitle,
            'company_name' => $companyName
        ]
    ]);
    } catch (\Exception $e) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()], 500);
    }
}

/**
 * Crée un contact avec l'IA pour une entreprise spécifique (utilisé dans ProjectController)
 */
function apiCreateContactWithAIForCompany($request) {
    try {
        $data = json_decode(file_get_contents('php://input'), true);
        $rawInput = $data['raw_input'] ?? '';
        $companyId = $data['company_id'] ?? null;

        if (!$rawInput) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Informations requises'], 400);
        }

        if (!$companyId) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Entreprise requise'], 400);
        }

        $pdo = \App\Core\Database::getInstance()->getConnection();

        // Récupérer la config AI
        $config = [];
        $rows = $pdo->query("SELECT `key`, `value` FROM ai_config")->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($rows as $row) {
            $config[$row['key']] = $row['value'];
        }

        // Récupérer le prompt pour contact_parse
        $stmt = $pdo->prepare("SELECT * FROM ai_prompts WHERE `key` = 'contact_parse' AND is_active = 1");
        $stmt->execute();
        $prompt = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$prompt || empty($config['api_key'])) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Configuration IA manquante'], 500);
        }

        // Départements disponibles
        $departmentsContext = "Départements valides: image, light, grip, sound, production, direction, art, post, other";

        // Préparer le prompt utilisateur
        $userPrompt = str_replace('{{raw_input}}', $rawInput, $prompt['user_prompt_template']);
        $userPrompt = str_replace('{{jobs_context}}', '', $userPrompt);
        $userPrompt = str_replace('{{departments_context}}', $departmentsContext, $userPrompt);

        // Appel OpenAI
        $ch = curl_init('https://api.openai.com/v1/chat/completions');
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $config['api_key']
            ],
            CURLOPT_POSTFIELDS => json_encode([
                'model' => $prompt['model'] ?? 'gpt-4o-mini',
                'messages' => [
                    ['role' => 'system', 'content' => $prompt['system_prompt']],
                    ['role' => 'user', 'content' => $userPrompt]
                ],
                'temperature' => (float)($prompt['temperature'] ?? 0.1),
                'max_tokens' => (int)($prompt['max_tokens'] ?? 500)
            ])
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Erreur API OpenAI'], 500);
        }

        $result = json_decode($response, true);
        $content = $result['choices'][0]['message']['content'] ?? '';

        // Parser le JSON retourné par IA
        $parsed = json_decode($content, true);
        if (!$parsed) {
            $content = preg_replace('/```json\s*|\s*```/', '', $content);
            $parsed = json_decode(trim($content), true);
        }

        if (!$parsed) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Réponse IA invalide'], 500);
        }

        $civility = trim($parsed['civility'] ?? '');
        $firstName = trim($parsed['first_name'] ?? '');
        $lastName = trim($parsed['last_name'] ?? '');
        $email = trim($parsed['email'] ?? '');
        $phone = normalizePhoneNumber($parsed['phone'] ?? '');
        $mobile = normalizePhoneNumber($parsed['mobile'] ?? $parsed['phone'] ?? '');
        $jobTitle = trim($parsed['job_title'] ?? $parsed['position'] ?? '');
        $departmentRaw = trim($parsed['department'] ?? '');

        // Normaliser la civilité
        if ($civility) {
            $civilityLower = strtolower($civility);
            if (strpos($civilityLower, 'mme') !== false || strpos($civilityLower, 'madame') !== false) {
                $civility = 'Mme';
            } else {
                $civility = 'M.';
            }
        }

        // Normaliser le département
        $validDepartments = ['image', 'light', 'grip', 'sound', 'production', 'direction', 'art', 'post', 'other'];
        $department = in_array(strtolower($departmentRaw), $validDepartments) ? strtolower($departmentRaw) : null;

        if (!$firstName && !$lastName && !$email) {
            return \App\Core\Response::json(['success' => false, 'error' => 'Impossible d\'extraire les informations du contact'], 400);
        }

        // Chercher si le contact existe déjà pour cette entreprise
        $existingContactId = null;

        if ($email) {
            $stmt = $pdo->prepare("
                SELECT c.id FROM contacts c
                INNER JOIN contact_companies cc ON c.id = cc.contact_id
                WHERE c.email = ? AND cc.company_id = ? AND c.deleted_at IS NULL LIMIT 1
            ");
            $stmt->execute([$email, $companyId]);
            $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
            if ($existing) {
                $existingContactId = $existing['id'];
            }
        }

        if (!$existingContactId && $firstName && $lastName) {
            $stmt = $pdo->prepare("
                SELECT c.id FROM contacts c
                INNER JOIN contact_companies cc ON c.id = cc.contact_id
                WHERE c.first_name = ? AND c.last_name = ? AND cc.company_id = ? AND c.deleted_at IS NULL LIMIT 1
            ");
            $stmt->execute([$firstName, $lastName, $companyId]);
            $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
            if ($existing) {
                $existingContactId = $existing['id'];
            }
        }

        $created = false;
        $contactId = $existingContactId;

        // Si le contact n'existe pas, le créer
        if (!$contactId) {
            $stmt = $pdo->prepare("
                INSERT INTO contacts (civility, first_name, last_name, email, phone, mobile, position, department, created_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
            ");
            $stmt->execute([
                $civility ?: null,
                $firstName ?: null,
                $lastName ?: null,
                $email ?: null,
                $phone ?: null,
                $mobile ?: null,
                $jobTitle ?: null,
                $department
            ]);
            $contactId = $pdo->lastInsertId();
            $created = true;

            // Lier le contact à l'entreprise
            $stmt = $pdo->prepare("
                INSERT INTO contact_companies (contact_id, company_id, is_primary, created_at)
                VALUES (?, ?, 1, NOW())
            ");
            $stmt->execute([$contactId, $companyId]);
        }

        return \App\Core\Response::json([
            'success' => true,
            'created' => $created,
            'contact_id' => $contactId,
            'data' => [
                'first_name' => $firstName,
                'last_name' => $lastName,
                'email' => $email,
                'phone' => $phone,
                'job_title' => $jobTitle
            ]
        ]);
    } catch (\Exception $e) {
        return \App\Core\Response::json(['success' => false, 'error' => 'Erreur: ' . $e->getMessage()], 500);
    }
}

/**
 * Normalise un numéro de téléphone au format français
 */
function normalizePhoneNumber($phone) {
    if (empty($phone)) return '';

    // Supprimer tous les caractères non numériques sauf le +
    $phone = preg_replace('/[^\d+]/', '', $phone);

    // Gérer le format international français +33
    if (strpos($phone, '+33') === 0) {
        $phone = '0' . substr($phone, 3);
    }
    // Gérer le format 0033
    if (strpos($phone, '0033') === 0) {
        $phone = '0' . substr($phone, 4);
    }

    // Formater avec des espaces (XX XX XX XX XX)
    if (strlen($phone) === 10 && $phone[0] === '0') {
        $phone = preg_replace('/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', '$1 $2 $3 $4 $5', $phone);
    }

    return $phone;
}
