<?php
/**
 * Projet                    : MageStock
 * Logiciel                  : MageStock
 * Fichier                   : api/warehouses.php
 * Rôle                      : API de lecture et de gestion contrôlée des magasins
 * Auteur                    : Régis KREMER
 * Version du fichier        : 2.6.116
 * Version générale          : 2.6.116
 * Lot                       : MAGESTOCK WAREHOUSE UI CONSOLIDATION1
 * Base requise              : MageStock 2.6.115
 * Création                  : 2026-02-21
 * Dernière modification     : 2026-07-25
 * Dépendances               : config.php, données JSON métier liées aux magasins
 * Données touchées          : warehouses.json uniquement lors d'une écriture validée
 * Permissions               : session authentifiée en lecture, warehouses.manage en écriture
 * Sécurité                  : CSRF, contrôle d'accès magasin, validation, suppression non destructive
 * Compatibilité             : PHP 8.1 à 8.4
 *
 * Résumé :
 * - expose les catégories sous forme de tableau sans modifier leur stockage historique ;
 * - conserve les champs adresse, contact, capacité, notes et couleur ;
 * - bloque la suppression tant que le magasin est référencé par une donnée métier.
 *
 * Historique :
 * - 2.6.116 — consolidation de l'interface magasins et suppression contrôlée sans cascade.
 * - 2.2.0 — API CRUD historique des magasins.
 */
require_once dirname(__DIR__) . '/config.php';
startSession();
requireAuth();

$method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
$body = json_decode((string)file_get_contents('php://input'), true);
if (!is_array($body)) $body = [];

function warehouseApiText($value, int $maxLength): string {
    $value = trim((string)$value);
    $value = str_replace(["\r", "\n", "\t"], ' ', $value);
    $value = preg_replace('/\s+/u', ' ', $value) ?: '';
    return function_exists('mb_substr') ? mb_substr($value, 0, $maxLength, 'UTF-8') : substr($value, 0, $maxLength);
}

function warehouseApiFold(string $value): string {
    if (function_exists('mb_strtolower')) return mb_strtolower($value, 'UTF-8');
    $value = strtr($value, [
        'À'=>'à','Á'=>'á','Â'=>'â','Ã'=>'ã','Ä'=>'ä','Å'=>'å','Æ'=>'æ','Ç'=>'ç','È'=>'è','É'=>'é','Ê'=>'ê','Ë'=>'ë',
        'Ì'=>'ì','Í'=>'í','Î'=>'î','Ï'=>'ï','Ð'=>'ð','Ñ'=>'ñ','Ò'=>'ò','Ó'=>'ó','Ô'=>'ô','Õ'=>'õ','Ö'=>'ö','Ø'=>'ø',
        'Ù'=>'ù','Ú'=>'ú','Û'=>'û','Ü'=>'ü','Ý'=>'ý','Þ'=>'þ','Œ'=>'œ','Š'=>'š','Ž'=>'ž','Ğ'=>'ğ','İ'=>'i','I'=>'ı',
        'А'=>'а','Б'=>'б','В'=>'в','Г'=>'г','Д'=>'д','Е'=>'е','Ё'=>'ё','Ж'=>'ж','З'=>'з','И'=>'и','Й'=>'й','К'=>'к','Л'=>'л','М'=>'м',
        'Н'=>'н','О'=>'о','П'=>'п','Р'=>'р','С'=>'с','Т'=>'т','У'=>'у','Ф'=>'ф','Х'=>'х','Ц'=>'ц','Ч'=>'ч','Ш'=>'ш','Щ'=>'щ','Ъ'=>'ъ',
        'Ы'=>'ы','Ь'=>'ь','Э'=>'э','Ю'=>'ю','Я'=>'я','Є'=>'є','І'=>'і','Ї'=>'ї','Ґ'=>'ґ'
    ]);
    return strtolower($value);
}

function warehouseApiCategories($value): array {
    if (is_array($value)) $categories = $value;
    elseif (is_string($value) && trim($value) !== '') {
        $decoded = json_decode($value, true);
        $categories = is_array($decoded) ? $decoded : [];
    } else $categories = [];

    $clean = [];
    foreach ($categories as $category) {
        $category = warehouseApiText($category, 120);
        if ($category === '') continue;
        $key = warehouseApiFold($category);
        $clean[$key] = $category;
    }
    $clean = array_values($clean);
    natcasesort($clean);
    return array_values($clean);
}

function warehouseApiIdList($value): array {
    if (is_string($value)) {
        $decoded = json_decode($value, true);
        if (is_array($decoded)) $value = $decoded;
    }
    if (!is_array($value)) return [];
    return array_values(array_unique(array_filter(array_map('intval', $value), static fn(int $id): bool => $id > 0)));
}

function warehouseApiReferencesId($value, int $warehouseId, string $parentKey = ''): bool {
    if (!is_array($value)) return false;
    foreach ($value as $key => $item) {
        $keyName = strtolower((string)$key);
        if (in_array($keyName, ['warehouseid', 'defaultwarehouse', 'transferto', 'draftwarehouseid'], true)) {
            if ((int)$item === $warehouseId) return true;
            continue;
        }
        if (in_array($keyName, ['allowedwarehouses', 'ldapdirectoryallowedwarehouses'], true)) {
            if (in_array($warehouseId, warehouseApiIdList($item), true)) return true;
            continue;
        }
        if (is_array($item) && warehouseApiReferencesId($item, $warehouseId, $keyName)) return true;
    }
    return false;
}

function warehouseApiDependencySummary(int $warehouseId): array {
    $sources = [
        'products' => 'products',
        'stock' => 'stock',
        'movements' => 'movements',
        'inventories' => 'inventories',
        'orders' => 'orders',
        'locations' => 'locations',
        'plans' => 'plans',
        'alerts' => 'alerts',
        'reservations' => 'reservations',
        'users' => 'users',
        'ldapMappings' => 'ldap_settings',
    ];
    $summary = [];
    foreach ($sources as $key => $entity) {
        $data = loadData($entity);
        $count = 0;
        if (array_is_list($data)) {
            foreach ($data as $record) {
                if (is_array($record) && warehouseApiReferencesId($record, $warehouseId)) $count++;
            }
        } elseif (warehouseApiReferencesId($data, $warehouseId)) {
            $count = 1;
        }
        $summary[$key] = $count;
    }
    return $summary;
}

function warehouseApiHasDependencies(array $summary): bool {
    foreach ($summary as $count) if ((int)$count > 0) return true;
    return false;
}

function warehouseApiFind(array $warehouses, int $id): ?array {
    foreach ($warehouses as $warehouse) {
        if ((int)($warehouse['id'] ?? 0) === $id) return $warehouse;
    }
    return null;
}

function warehouseApiNameExists(array $warehouses, string $name, int $ignoreId = 0): bool {
    $needle = warehouseApiFold($name);
    foreach ($warehouses as $warehouse) {
        if ((int)($warehouse['id'] ?? 0) === $ignoreId) continue;
        $candidate = warehouseApiText($warehouse['name'] ?? '', 120);
        $candidate = warehouseApiFold($candidate);
        if ($candidate !== '' && $candidate === $needle) return true;
    }
    return false;
}

function warehouseApiFields(array $input, ?array $existing = null): array {
    $fields = [];
    $fields['name'] = warehouseApiText($input['name'] ?? ($existing['name'] ?? ''), 120);
    $fields['address'] = warehouseApiText($input['address'] ?? ($existing['address'] ?? ''), 240);
    $fields['contact'] = warehouseApiText($input['contact'] ?? ($existing['contact'] ?? ''), 160);
    $fields['notes'] = warehouseApiText($input['notes'] ?? ($existing['notes'] ?? ''), 1000);

    $capacityRaw = $input['capacity'] ?? ($existing['capacity'] ?? null);
    $fields['capacity'] = ($capacityRaw === null || $capacityRaw === '') ? null : max(0, (float)$capacityRaw);

    $color = warehouseApiText($input['color'] ?? ($existing['color'] ?? '#00b4d8'), 40);
    if (!preg_match('/^(?:#[0-9a-f]{3,8}|rgba?\([0-9.,%\s]+\)|[a-z]+)$/i', $color)) $color = '#00b4d8';
    $fields['color'] = $color;
    return $fields;
}

switch ($method) {
    case 'GET':
        $warehouses = loadData('warehouses');
        $allowed = getUserAllowedWarehouses();
        if ($allowed !== null) {
            $warehouses = array_values(array_filter($warehouses, static fn(array $warehouse): bool => in_array((int)($warehouse['id'] ?? 0), $allowed, true)));
        }
        $warehouses = array_map(static function(array $warehouse): array {
            $warehouse['categories'] = warehouseApiCategories($warehouse['categories'] ?? []);
            return $warehouse;
        }, $warehouses);
        jsonResponse($warehouses);

    case 'POST':
        requirePerm('warehouses.manage');
        csrfCheck();
        $warehouses = loadData('warehouses');
        $fields = warehouseApiFields($body);
        if ($fields['name'] === '') jsonError('Nom obligatoire.', 422);
        if (warehouseApiNameExists($warehouses, $fields['name'])) jsonError('Un magasin porte déjà ce nom.', 409);
        $fields['categories'] = '[]';
        jsonResponse(addItem('warehouses', $fields), 201);

    case 'PUT':
        requirePerm('warehouses.manage');
        csrfCheck();
        $id = (int)($body['id'] ?? 0);
        if ($id <= 0) jsonError('ID manquant.', 422);
        $warehouses = loadData('warehouses');
        $existing = warehouseApiFind($warehouses, $id);
        if (!$existing) jsonError('Magasin introuvable.', 404);
        $fields = warehouseApiFields($body, $existing);
        if ($fields['name'] === '') jsonError('Nom obligatoire.', 422);
        if (warehouseApiNameExists($warehouses, $fields['name'], $id)) jsonError('Un magasin porte déjà ce nom.', 409);
        $updated = updateItem('warehouses', $id, $fields);
        $updated ? jsonResponse($updated) : jsonError('Magasin introuvable.', 404);

    case 'DELETE':
        requirePerm('warehouses.manage');
        csrfCheck();
        $id = (int)($body['id'] ?? $_GET['id'] ?? 0);
        if ($id <= 0) jsonError('ID manquant.', 422);
        $warehouses = loadData('warehouses');
        $existing = warehouseApiFind($warehouses, $id);
        if (!$existing) jsonError('Magasin introuvable.', 404);

        $dependencies = warehouseApiDependencySummary($id);
        if (warehouseApiHasDependencies($dependencies)) {
            jsonResponse([
                'error' => 'Suppression impossible : ce magasin est encore utilisé. Réaffectez les éléments liés avant de le supprimer.',
                'dependencies' => $dependencies,
            ], 409);
        }

        if (!deleteItem('warehouses', $id)) jsonError('Suppression impossible.', 500);
        jsonResponse(['ok' => true, 'id' => $id]);

    default:
        jsonError('Méthode non supportée.', 405);
}
