<?php
declare(strict_types=1);

/* doc-project | caisse-aqp/public/api/_lib/tempAddress.php | Centralise la normalisation, la persistance et la résolution de l’adresse de livraison provisoire portée par la commande via pos_temp_adresses, avec contrôle du couple ville / code postal autorisé selon le PDV. | Expose: tempAddressCleanString, tempAddressNormalizePayload, tempAddressFetch, tempAddressPersist, tempAddressToApi, tempAddressFromClient, tempAddressResolveEffective | Dépend de: PDO, pos_temp_adresses, std_clients, deliveryCityChoices.php | Impacte: persistance d’adresse provisoire, payloads API commande, résolution d’adresse effective | Tables: pos_temp_adresses(id, adresse, complement_adresse, code_postal, ville, explications, numero_urgence, latitude, longitude), std_clients(adresse, complement_adresse, code_postal, ville) */

require_once __DIR__ . '/deliveryCityChoices.php';

function tempAddressCleanString($value, int $maxLen = 0): string
{
    $s = trim((string)($value ?? ''));
    $s = preg_replace('~\s+~u', ' ', $s);
    if (!is_string($s)) $s = '';
    if ($maxLen > 0) {
        if (function_exists('mb_strlen') && function_exists('mb_substr')) {
            if (mb_strlen($s, 'UTF-8') > $maxLen) $s = (string)mb_substr($s, 0, $maxLen, 'UTF-8');
        } else {
            if (strlen($s) > $maxLen) $s = substr($s, 0, $maxLen);
        }
    }
    return trim($s);
}

function tempAddressNormalizePayload($payload, string $storeId = ''): ?array
{
    if (!is_array($payload)) return null;

    $enabledRaw = $payload['enabled'] ?? $payload['active'] ?? true;
    $enabled = ($enabledRaw === true || $enabledRaw === 1 || $enabledRaw === '1' || $enabledRaw === 'true');
    if (!$enabled) return null;

    $codePostal = preg_replace('~\D+~', '', (string)($payload['code_postal'] ?? $payload['codePostal'] ?? ''));
    if (!is_string($codePostal)) $codePostal = '';

    $out = [
        'adresse' => tempAddressCleanString($payload['adresse'] ?? '', 190),
        'complement_adresse' => tempAddressCleanString($payload['complement_adresse'] ?? $payload['complementAdresse'] ?? '', 190),
        'code_postal' => trim($codePostal),
        'ville' => tempAddressCleanString($payload['ville'] ?? '', 120),
        'explications' => tempAddressCleanString($payload['explications'] ?? '', 500),
        'numero_urgence' => tempAddressCleanString($payload['numero_urgence'] ?? $payload['numeroUrgence'] ?? '', 30),
    ];

    $hasAny = false;
    foreach ($out as $value) {
        if ($value !== '') {
            $hasAny = true;
            break;
        }
    }
    if (!$hasAny) return null;

    if ($out['adresse'] === '' || $out['code_postal'] === '' || $out['ville'] === '') {
        return null;
    }

    if ($storeId !== '') {
        $normalized = caisseNormalizeDeliveryCityPayload($out, $storeId, 'ville', 'code_postal');
        if (empty($normalized['ok']) || !is_array($normalized['payload'])) {
            return null;
        }
        $out = $normalized['payload'];
    }

    return $out;
}

function tempAddressFetch(PDO $pdo, int $id): ?array
{
    if ($id <= 0) return null;
    $stmt = $pdo->prepare('SELECT * FROM pos_temp_adresses WHERE id = :id LIMIT 1');
    $stmt->bindValue(':id', $id, PDO::PARAM_INT);
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return is_array($row) ? $row : null;
}

function tempAddressPersist(PDO $pdo, $payload, ?int $existingId = null, string $storeId = ''): ?int
{
    $data = tempAddressNormalizePayload($payload, $storeId);
    if ($data === null) return null;

    $existingId = (int)($existingId ?? 0);
    if ($existingId > 0 && tempAddressFetch($pdo, $existingId)) {
        $stmt = $pdo->prepare(
            'UPDATE pos_temp_adresses
             SET adresse = :adresse,
                 complement_adresse = :complement_adresse,
                 code_postal = :code_postal,
                 ville = :ville,
                 explications = :explications,
                 numero_urgence = :numero_urgence
             WHERE id = :id'
        );
        $stmt->bindValue(':id', $existingId, PDO::PARAM_INT);
        $stmt->bindValue(':adresse', $data['adresse'], PDO::PARAM_STR);
        $stmt->bindValue(':complement_adresse', $data['complement_adresse'], PDO::PARAM_STR);
        $stmt->bindValue(':code_postal', $data['code_postal'], PDO::PARAM_STR);
        $stmt->bindValue(':ville', $data['ville'], PDO::PARAM_STR);
        $stmt->bindValue(':explications', $data['explications'], PDO::PARAM_STR);
        $stmt->bindValue(':numero_urgence', $data['numero_urgence'], PDO::PARAM_STR);
        $stmt->execute();
        return $existingId;
    }

    $stmt = $pdo->prepare(
        'INSERT INTO pos_temp_adresses (
            adresse,
            complement_adresse,
            code_postal,
            ville,
            explications,
            numero_urgence
        ) VALUES (
            :adresse,
            :complement_adresse,
            :code_postal,
            :ville,
            :explications,
            :numero_urgence
        )'
    );
    $stmt->bindValue(':adresse', $data['adresse'], PDO::PARAM_STR);
    $stmt->bindValue(':complement_adresse', $data['complement_adresse'], PDO::PARAM_STR);
    $stmt->bindValue(':code_postal', $data['code_postal'], PDO::PARAM_STR);
    $stmt->bindValue(':ville', $data['ville'], PDO::PARAM_STR);
    $stmt->bindValue(':explications', $data['explications'], PDO::PARAM_STR);
    $stmt->bindValue(':numero_urgence', $data['numero_urgence'], PDO::PARAM_STR);
    $stmt->execute();
    $newId = (int)$pdo->lastInsertId();
    return ($newId > 0) ? $newId : null;
}

function tempAddressToApi(?array $row): ?array
{
    if (!is_array($row)) return null;
    return [
        'id' => (int)($row['id'] ?? 0),
        'adresse' => (string)($row['adresse'] ?? ''),
        'complement_adresse' => (string)($row['complement_adresse'] ?? ''),
        'code_postal' => (string)($row['code_postal'] ?? ''),
        'ville' => (string)($row['ville'] ?? ''),
        'explications' => (string)($row['explications'] ?? ''),
        'numero_urgence' => (string)($row['numero_urgence'] ?? ''),
        'latitude' => isset($row['latitude']) ? (string)$row['latitude'] : '',
        'longitude' => isset($row['longitude']) ? (string)$row['longitude'] : '',
    ];
}

function tempAddressFromClient(?array $client): ?array
{
    if (!is_array($client)) return null;
    $adresse = tempAddressCleanString($client['adresse'] ?? '', 190);
    $codePostal = tempAddressCleanString($client['code_postal'] ?? '', 20);
    $ville = tempAddressCleanString($client['ville'] ?? '', 120);
    if ($adresse === '' || $codePostal === '' || $ville === '') return null;
    return [
        'adresse' => $adresse,
        'complement_adresse' => tempAddressCleanString($client['complement_adresse'] ?? '', 190),
        'code_postal' => $codePostal,
        'ville' => $ville,
        'explications' => '',
        'numero_urgence' => '',
        'latitude' => isset($client['latitude']) ? (string)$client['latitude'] : '',
        'longitude' => isset($client['longitude']) ? (string)$client['longitude'] : '',
    ];
}

function tempAddressResolveEffective(?array $client, ?array $tempAddress): ?array
{
    $tempApi = tempAddressToApi($tempAddress);
    if (is_array($tempApi) && trim((string)($tempApi['adresse'] ?? '')) !== '') {
        return $tempApi;
    }
    return tempAddressFromClient($client);
}