<?php

namespace Core\App\Integrations\Shipping;

/**
 * ZR Express (ProColis) Client
 * Base URL: https://procolis.com/api_v1
 * Auth: headers token + key
 */
class ZrExpressClient
{
    private string $baseUrl = 'https://procolis.com/api_v1';
    private string $token;
    private string $key;

    /** ZR Express return/cancelled statuses (from their status field) */
    public const RETURN_STATUSES = [
        'retour',
        'retourné',
        'retourne',
        'retour_en_cours',
        'retour reçu',
        'retour recu',
        'returned',
        'annulé',
        'annule',
    ];

    public const DELIVERED_STATUSES = [
        'livré',
        'livre',
        'livree',
        'livrée',
        'delivered',
    ];

    public function __construct(string $token, string $key)
    {
        $this->token = $token;
        $this->key   = $key;
    }

    /* =====================================================
       Validate token
    ===================================================== */
    public function validateToken(): array
    {
        return $this->get('/token');
    }

    /* =====================================================
       Read parcel(s) status
    ===================================================== */
    public function readParcels(array $trackings): array
    {
        $body = ['Colis' => array_map(fn($t) => ['Tracking' => $t], $trackings)];
        return $this->post('/lire', $body);
    }

    /* =====================================================
       Get single parcel tracking info
    ===================================================== */
    public function track(string $tracking): array
    {
        $result = $this->readParcels([$tracking]);

        if (empty($result['Colis']) || !is_array($result['Colis'])) {
            return ['success' => false, 'error' => 'no_data'];
        }

        foreach ($result['Colis'] as $colis) {
            if (
                isset($colis['Tracking']) &&
                strtolower($colis['Tracking']) === strtolower($tracking)
            ) {
                $status = strtolower(trim($colis['Situation'] ?? $colis['status'] ?? ''));
                return [
                    'success' => true,
                    'status'  => $status,
                    'raw'     => $colis,
                ];
            }
        }

        // Return first result if tracking key doesn't match
        $first  = $result['Colis'][0] ?? [];
        $status = strtolower(trim($first['Situation'] ?? $first['status'] ?? ''));
        return [
            'success' => !empty($first),
            'status'  => $status,
            'raw'     => $first,
        ];
    }

    /* =====================================================
       Check if a ZR status means returned
    ===================================================== */
    public static function isReturnStatus(string $status): bool
    {
        $s = mb_strtolower(trim($status));
        foreach (self::RETURN_STATUSES as $r) {
            if (str_contains($s, $r) || str_contains(mb_strtolower($r), $s)) {
                return true;
            }
        }
        return false;
    }

    public static function isDeliveredStatus(string $status): bool
    {
        $s = mb_strtolower(trim($status));
        foreach (self::DELIVERED_STATUSES as $d) {
            if (str_contains($s, $d)) {
                return true;
            }
        }
        return false;
    }

    /* =====================================================
       HTTP helpers
    ===================================================== */
    private function get(string $endpoint): array
    {
        $ch = curl_init($this->baseUrl . $endpoint);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                'token: ' . $this->token,
                'key: '   . $this->key,
                'Content-Type: application/json',
            ],
            CURLOPT_TIMEOUT => 20,
        ]);
        $res = curl_exec($ch);
        curl_close($ch);
        return json_decode((string)$res, true) ?: [];
    }

    private function post(string $endpoint, array $body): array
    {
        $ch = curl_init($this->baseUrl . $endpoint);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_HTTPHEADER     => [
                'token: ' . $this->token,
                'key: '   . $this->key,
                'Content-Type: application/json',
            ],
            CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE),
            CURLOPT_TIMEOUT    => 20,
        ]);
        $res = curl_exec($ch);
        curl_close($ch);
        return json_decode((string)$res, true) ?: [];
    }
}
