<?php
/**
 * Projet                    : MageStock
 * Logiciel                  : MageStock
 * Fichier                   : api/warehouse-categories.php
 * Rôle                      : API des catégories personnalisées rattachées aux 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, warehouses.json
 * Données touchées          : champ categories de warehouses.json
 * Permissions               : session et accès magasin en lecture, warehouses.manage en écriture
 * Sécurité                  : CSRF, validation, contrôle d'accès et encodage JSON stable
 * Compatibilité             : PHP 8.1 à 8.4
 *
 * Résumé :
 * - accepte le stockage historique sous forme JSON et les tableaux déjà normalisés ;
 * - garantit des catégories uniques, triées et correctement encodées ;
 * - aligne les droits d'écriture sur la permission warehouses.manage.
 *
 * Historique :
 * - 2.6.116 — normalisation du contrat catégories et consolidation des permissions.
 * - 2.2.0 — CRUD catégories par magasin.
 */
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 warehouseCategoryText($value, int $maxLength = 120): 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 warehouseCategoryFold(string $value): string {
    if (function_exists('mb_strtolower')) return mb_strtolower($value, 'UTF-8');
    $value = strtr($value, [
        'À'=>'à','Á'=>'á','Â'=>'â','Ã'=>'ã','Ä'=>'ä','Å'=>'å','Æ'=>'æ','Ç'=>'ç','È'=>'è','É'=>'é','Ê'=>'ê','Ë'=>'ë',
        'Ì'=>'ì','Í'=>'í','Î'=>'î','Ï'=>'ï','Ð'=>'ð','Ñ'=>'ñ','Ò'=>'ò','Ó'=>'ó','Ô'=>'ô','Õ'=>'õ','Ö'=>'ö','Ø'=>'ø',
        'Ù'=>'ù','Ú'=>'ú','Û'=>'û','Ü'=>'ü','Ý'=>'ý','Þ'=>'þ','Œ'=>'œ','Š'=>'š','Ž'=>'ž','Ğ'=>'ğ','İ'=>'i','I'=>'ı',
        'А'=>'а','Б'=>'б','В'=>'в','Г'=>'г','Д'=>'д','Е'=>'е','Ё'=>'ё','Ж'=>'ж','З'=>'з','И'=>'и','Й'=>'й','К'=>'к','Л'=>'л','М'=>'м',
        'Н'=>'н','О'=>'о','П'=>'п','Р'=>'р','С'=>'с','Т'=>'т','У'=>'у','Ф'=>'ф','Х'=>'х','Ц'=>'ц','Ч'=>'ч','Ш'=>'ш','Щ'=>'щ','Ъ'=>'ъ',
        'Ы'=>'ы','Ь'=>'ь','Э'=>'э','Ю'=>'ю','Я'=>'я','Є'=>'є','І'=>'і','Ї'=>'ї','Ґ'=>'ґ'
    ]);
    return strtolower($value);
}

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

    $clean = [];
    foreach ($list as $category) {
        $category = warehouseCategoryText($category);
        if ($category === '') continue;
        $key = warehouseCategoryFold($category);
        $clean[$key] = $category;
    }
    $clean = array_values($clean);
    natcasesort($clean);
    return array_values($clean);
}

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

function warehouseCategoryContains(array $categories, string $needle): bool {
    $needle = warehouseCategoryFold($needle);
    foreach ($categories as $category) {
        $candidate = warehouseCategoryFold((string)$category);
        if ($candidate === $needle) return true;
    }
    return false;
}

$warehouseId = (int)($_GET['warehouseId'] ?? $body['warehouseId'] ?? 0);
if ($warehouseId <= 0) jsonError('warehouseId requis.', 422);
if (!userCanAccessWarehouse($warehouseId)) jsonError('Accès interdit à ce magasin.', 403);

$warehouses = loadData('warehouses');
$index = warehouseCategoryFindIndex($warehouses, $warehouseId);
if ($index === null) jsonError('Magasin introuvable.', 404);
$categories = warehouseCategoryList($warehouses[$index]['categories'] ?? []);

if ($method === 'GET') jsonResponse(['categories' => $categories]);

requirePerm('warehouses.manage');
csrfCheck();

switch ($method) {
    case 'POST':
        $category = warehouseCategoryText($body['category'] ?? '');
        if ($category === '') jsonError('Nom de catégorie obligatoire.', 422);
        if (warehouseCategoryContains($categories, $category)) jsonError('Cette catégorie existe déjà.', 409);
        $categories[] = $category;
        natcasesort($categories);
        $categories = array_values($categories);
        $warehouses[$index]['categories'] = json_encode($categories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $warehouses[$index]['updatedAt'] = date('c');
        saveData('warehouses', $warehouses);
        jsonResponse(['success' => true, 'categories' => $categories], 201);

    case 'PUT':
        $oldName = warehouseCategoryText($body['oldCategory'] ?? '');
        $newName = warehouseCategoryText($body['newCategory'] ?? '');
        if ($oldName === '' || $newName === '') jsonError('Ancien et nouveau noms requis.', 422);
        if (!warehouseCategoryContains($categories, $oldName)) jsonError('Catégorie introuvable.', 404);
        if (warehouseCategoryFold($oldName) !== warehouseCategoryFold($newName) && warehouseCategoryContains($categories, $newName)) jsonError('Le nouveau nom existe déjà.', 409);
        foreach ($categories as &$category) {
            if (warehouseCategoryFold((string)$category) === warehouseCategoryFold($oldName)) $category = $newName;
        }
        unset($category);
        natcasesort($categories);
        $categories = array_values($categories);
        $warehouses[$index]['categories'] = json_encode($categories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $warehouses[$index]['updatedAt'] = date('c');
        saveData('warehouses', $warehouses);
        jsonResponse(['success' => true, 'categories' => $categories]);

    case 'DELETE':
        $category = warehouseCategoryText($body['category'] ?? '');
        if ($category === '') jsonError('Nom de catégorie obligatoire.', 422);
        $foldedCategory = warehouseCategoryFold($category);
        $categories = array_values(array_filter($categories, static fn(string $item): bool => warehouseCategoryFold($item) !== $foldedCategory));
        natcasesort($categories);
        $categories = array_values($categories);
        $warehouses[$index]['categories'] = json_encode($categories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $warehouses[$index]['updatedAt'] = date('c');
        saveData('warehouses', $warehouses);
        jsonResponse(['success' => true, 'deleted' => true, 'categories' => $categories]);

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