<?php

namespace Core\App\Integrations\Shipping;

/**
 * Yalidine API Client
 * Docs: https://api.yalidine.app/
 * Auth: X-API-ID + X-API-TOKEN headers
 */
class YalidineClient
{
    protected string $baseUrl = 'https://api.yalidine.app/v1';
    protected string $apiId;
    protected string $apiToken;

    public function __construct(string $apiToken, string $apiId = '')
    {
        $this->apiToken = trim($apiToken);
        $this->apiId    = trim($apiId);
    }

    /* =====================================================
       Test Connection
    ===================================================== */
    public function testConnection(): array
    {
        return $this->request('GET', '/wilayas?page_size=1');
    }

    /* =====================================================
       Wilayas
    ===================================================== */
    public function getWilayas(): array
    {
        return $this->request('GET', '/wilayas?page_size=58');
    }

    /* =====================================================
       Communes by Wilaya
    ===================================================== */
    public function getCommunes(int $wilayaId): array
    {
        return $this->request('GET', '/communes?wilaya_id=' . $wilayaId . '&page_size=200');
    }

    /* =====================================================
       Delivery Fees
    ===================================================== */
    public function getFees(?int $fromWilaya = null, ?int $toWilaya = null): array
    {
        $params = [];
        if ($fromWilaya !== null) $params['from_wilaya_id'] = $fromWilaya;
        if ($toWilaya !== null)   $params['to_wilaya_id']   = $toWilaya;

        $query = $params ? '?' . http_build_query($params) : '';
        return $this->request('GET', '/deliveryfees' . $query);
    }

    /* =====================================================
       Create Parcel
       حقول Yalidine الإلزامية:
       - firstname, familyname, contact_phone, address
       - from_wilaya_id, to_wilaya_id, to_commune_id
       - product_list, price, do_insurance
       - declared_value, length, width, height, weight
       - freeshipping, is_stopdesk, stopdesk_id (if stopdesk)
    ===================================================== */
    public function createParcel(array $data): array
    {
        return $this->request('POST', '/parcels', $data);
    }

    /* =====================================================
       Get Parcel by tracking
    ===================================================== */
    public function getParcel(string $tracking): array
    {
        return $this->request('GET', '/parcels/' . urlencode($tracking));
    }

    /* =====================================================
       Get Parcel Label (PDF)
    ===================================================== */
    public function getLabel(string $tracking): array
    {
        return $this->request('GET', '/parcels/' . urlencode($tracking) . '/label', [], true);
    }

    /* =====================================================
       Get Stop Desks (for desk delivery)
    ===================================================== */
    public function getStopDesks(?int $wilayaId = null): array
    {
        $query = $wilayaId ? '?wilaya_id=' . $wilayaId : '';
        return $this->request('GET', '/stopdesks' . $query);
    }

    /* =====================================================
       Internal HTTP Client
    ===================================================== */
    protected function request(
        string $method,
        string $endpoint,
        array  $payload = [],
        bool   $rawResponse = false
    ): array {
        $url = rtrim($this->baseUrl, '/') . $endpoint;

        $ch = curl_init($url);

        $headers = [
            'Accept: application/json',
            'X-API-ID: '    . $this->apiId,
            'X-API-TOKEN: ' . $this->apiToken,
        ];

        $opts = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST  => $method,
            CURLOPT_HTTPHEADER     => $headers,
            CURLOPT_TIMEOUT        => 30,
        ];

        if ($method === 'POST' && !empty($payload)) {
            $headers[]  = 'Content-Type: application/json';
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            $opts[CURLOPT_POSTFIELDS] = json_encode($payload, JSON_UNESCAPED_UNICODE);
        }

        curl_setopt_array($ch, $opts);

        $body      = curl_exec($ch);
        $httpCode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($curlError) {
            return ['success' => false, 'error' => 'CURL_ERROR', 'message' => $curlError];
        }

        if ($rawResponse) {
            return ['success' => $httpCode >= 200 && $httpCode < 300, 'raw' => $body, 'status' => $httpCode];
        }

        $decoded = json_decode($body, true);

        if ($httpCode >= 200 && $httpCode < 300) {
            return ['success' => true, 'status' => $httpCode, 'data' => $decoded];
        }

        return [
            'success' => false,
            'status'  => $httpCode,
            'error'   => $decoded['message'] ?? 'Yalidine API error',
            'raw'     => $decoded,
        ];
    }
}