<?php
/**
 * Fichier  : api/ldap.php
 * Auteur   : KREMER Régis
 * Version  : 2.6.102
 * Date     : 2026-07-21
 * Description : API administrateur LDAP / Active Directory : configuration, secrets,
 *               diagnostics, tests, simulation des droits et synchronisation.
 */
require_once dirname(__DIR__) . '/config.php';
require_once dirname(__DIR__) . '/includes/ldap-helper.php';
startSession();
requireAdmin();
requirePerm('ldap.manage');

$method = $_SERVER['REQUEST_METHOD'];
$action = trim((string)($_GET['action'] ?? 'config'));
$actor = currentUser();

function ldapApiBody(): array {
    $body = json_decode(file_get_contents('php://input'), true);
    return is_array($body) ? $body : [];
}
function ldapApiRateLimit(string $action): void {
    $ip = (string)($_SERVER['REMOTE_ADDR'] ?? 'cli');
    if (!checkRateLimit('ldap_admin_' . md5($ip . '|' . $action), 20, 300)) {
        jsonError('Trop de tests LDAP. Patientez quelques minutes.', 429);
    }
}
function ldapApiDraftConfig(array $body): array {
    $input = is_array($body['config'] ?? null) ? $body['config'] : magestockLdapReadConfig();
    // Les diagnostics ne doivent jamais activer ou remplacer la configuration en production.
    $input['enabled'] = false;
    return magestockLdapNormalizeConfig($input, true);
}
function ldapApiSafeProfile(array $profile): array {
    return [
        'username'=>$profile['username'] ?? '', 'name'=>$profile['name'] ?? '', 'firstName'=>$profile['firstName'] ?? '',
        'lastName'=>$profile['lastName'] ?? '', 'email'=>$profile['email'] ?? '', 'ldapDn'=>$profile['ldapDn'] ?? '',
        'ldapId'=>$profile['ldapId'] ?? '', 'ldapGroups'=>$profile['ldapGroups'] ?? [], 'role'=>$profile['role'] ?? 'user',
        'allowedWarehouses'=>$profile['allowedWarehouses'] ?? [],
    ];
}

try {
    if ($method === 'GET') {
        if ($action === 'config') jsonResponse(['config'=>magestockLdapPublicConfig(magestockLdapReadConfig()), 'diagnostics'=>magestockLdapDiagnostics()]);
        if ($action === 'diagnostics') jsonResponse(magestockLdapDiagnostics());
        if ($action === 'audit') {
            $entries = json_decode((string)@file_get_contents(MAGESTOCK_LDAP_AUDIT_FILE), true);
            if (!is_array($entries)) $entries=[];
            jsonResponse(array_reverse(array_slice($entries, -100)));
        }
        jsonError('Action LDAP inconnue.', 404);
    }

    csrfCheck();
    ldapApiRateLimit($action);
    $body = ldapApiBody();

    switch ($action) {
        case 'saveConfig':
            $config = is_array($body['config'] ?? null) ? $body['config'] : $body;
            $saved = magestockLdapSaveConfig($config, $actor, trim((string)($body['confirmation'] ?? '')));
            jsonResponse(['config'=>magestockLdapPublicConfig($saved), 'diagnostics'=>magestockLdapDiagnostics()]);

        case 'setSecret':
            magestockLdapSetBindSecret((string)($body['secret'] ?? ''), $actor);
            jsonResponse(['secretConfigured'=>true]);

        case 'deleteSecret':
            magestockLdapDeleteBindSecret($actor);
            jsonResponse(['secretConfigured'=>false]);

        case 'setCertificate':
            magestockLdapSetCaCertificate((string)($body['pem'] ?? ''), $actor);
            jsonResponse(['caCertificateConfigured'=>true]);

        case 'deleteCertificate':
            magestockLdapDeleteCaCertificate($actor);
            jsonResponse(['caCertificateConfigured'=>false]);

        case 'testConnection':
            $cfg = ldapApiDraftConfig($body);
            $meta = null; $conn = magestockLdapConnect($cfg, $meta);
            if (is_object($conn) || is_resource($conn)) @ldap_unbind($conn);
            magestockLdapAudit('test_connection_success', ['server'=>$meta['host'] ?? '','durationMs'=>$meta['durationMs'] ?? 0], $actor);
            jsonResponse(['ok'=>true,'connection'=>$meta]);

        case 'testBind':
            $cfg = ldapApiDraftConfig($body);
            $meta = null; $conn = magestockLdapServiceConnection($cfg, $meta);
            try { /* bind technique déjà validé avec bascule serveur */ }
            finally { if (is_object($conn) || is_resource($conn)) @ldap_unbind($conn); }
            magestockLdapAudit('test_bind_success', ['server'=>$meta['host'] ?? '','durationMs'=>$meta['durationMs'] ?? 0], $actor);
            jsonResponse(['ok'=>true,'connection'=>$meta]);

        case 'testSearch':
            $username = trim((string)($body['username'] ?? ''));
            if ($username === '') jsonError('Identifiant de test obligatoire.', 422);
            $cfg = ldapApiDraftConfig($body);
            $meta = null; $conn = magestockLdapServiceConnection($cfg, $meta);
            try {
                $entry = magestockLdapSearchUser($conn, $cfg, $username);
                $groups = magestockLdapReadGroups($conn, $entry, $cfg, $username);
                $disabled = magestockLdapIsDisabled($entry, $cfg);
                $profile = magestockLdapBuildProfile($entry, $groups, ['role'=>'user','allowedWarehouses'=>[],'permissions'=>[]], $cfg, $username);
            } finally { if (is_object($conn) || is_resource($conn)) @ldap_unbind($conn); }
            magestockLdapAudit('test_search_success', ['username'=>$username,'groups'=>count($groups)], $actor);
            jsonResponse(['ok'=>true,'connection'=>$meta,'profile'=>ldapApiSafeProfile($profile),'disabled'=>$disabled,'groupCount'=>count($groups)]);

        case 'simulate':
            $username = trim((string)($body['username'] ?? ''));
            if ($username === '') jsonError('Identifiant de test obligatoire.', 422);
            $cfg = ldapApiDraftConfig($body);
            $result = magestockLdapInspectUser($username, $cfg);
            magestockLdapAudit('simulate_access_success', ['username'=>$username,'role'=>$result['access']['role'] ?? '','groups'=>count($result['profile']['ldapGroups'] ?? [])], $actor);
            jsonResponse(['ok'=>true,'connection'=>$result['connection'],'profile'=>ldapApiSafeProfile($result['profile']),'access'=>$result['access'],'disabled'=>$result['disabled']]);

        case 'testAuthentication':
            $username = trim((string)($body['username'] ?? ''));
            $password = (string)($body['password'] ?? '');
            if ($username === '' || $password === '') jsonError('Identifiant et mot de passe de test obligatoires.', 422);
            $cfg = ldapApiDraftConfig($body);
            $result = magestockLdapTestAuthentication($username, $password, $cfg);
            $cfg = magestockLdapMarkSuccessfulTest($cfg, $username, $actor);
            jsonResponse(['ok'=>true,'connection'=>$result['connection'],'profile'=>ldapApiSafeProfile($result['profile']),'access'=>$result['access'],'config'=>magestockLdapPublicConfig($cfg)]);

        case 'syncKnownUsers':
            jsonResponse(magestockLdapSyncKnownUsers($actor));

        default:
            jsonError('Action LDAP inconnue.', 404);
    }
} catch (MageStockLdapException $e) {
    magestockLdapMarkError($e->reasonCode, $actor);
    jsonResponse(['error'=>$e->publicMessage,'code'=>$e->reasonCode], 422);
} catch (Throwable $e) {
    magestockLdapMarkError('unexpected_error', $actor);
    error_log('[MageStock LDAP] ' . $e->getMessage());
    jsonResponse(['error'=>'Erreur LDAP inattendue. Consultez le diagnostic serveur.','code'=>'unexpected_error'], 500);
}
