<?php
namespace EasyChat\Library\Delivery;

use EasyChat\Library\Http\ExternalHttpClient;

 
final class ApiShipTrackingProvider implements ShipmentAwareTrackingProviderInterface
{
    private const ENDPOINT='https://api.apiship.ru/v1/orders/status'; private $http; private $token;
    public function __construct($registry,string $token,?ExternalHttpClient $http=null){$this->http=$http?:new ExternalHttpClient($registry);$this->token=trim($token);}
    public function code():string{return 'apiship';}
    public function supports(string $carrier,string $number):bool{return (bool)preg_match('/apiship|апишип/ui',$carrier)&&(bool)preg_match('/^[A-Za-z0-9_.:-]{1,80}$/',$number);}
    public function track(string $number):array{
        if($this->token===''||!$this->supports('ApiShip',$number))return array('status'=>'unavailable');
        $r=$this->http->request('GET',self::ENDPOINT.'?clientNumber='.rawurlencode($number),array('headers'=>array('Authorization: '.$this->token,'Accept: application/json'),'connect_timeout'=>4,'timeout'=>12,'trust_profile'=>'apiship_tracking'));
        return $this->parse($r, $number);
    }
    public function trackShipment(array $shipment): array {
        $number = preg_replace('/\s+/', '', trim((string)($shipment['client_number'] ?? $shipment['tracking_number'] ?? '')));
        if ($this->token === '' || !$this->supports('ApiShip', $number)) return array('status' => 'unavailable');
        $external_order_id = trim((string)($shipment['external_order_id'] ?? ''));
         
         
        $url = preg_match('/^[1-9][0-9]{0,18}$/', $external_order_id)
            ? 'https://api.apiship.ru/v1/orders/' . rawurlencode($external_order_id) . '/status'
            : self::ENDPOINT . '?clientNumber=' . rawurlencode($number);
        $r = $this->http->request('GET', $url, array('headers'=>array('Authorization: '.$this->token,'Accept: application/json'),'connect_timeout'=>4,'timeout'=>12,'trust_profile'=>'apiship_tracking'));
        return $this->parse($r, $number, $external_order_id);
    }
    private function parse(array $r, string $number, string $external_order_id = ''): array {
        if(empty($r['transport_ok']))return array('status'=>'unavailable');$code=(int)($r['http_code']??0);if($code===404)return array('status'=>'not_found');if($code<200||$code>=300)return array('status'=>'unavailable');$data=json_decode((string)($r['raw']??''),true);if(!is_array($data))return array('status'=>'unavailable');
        $statuses=(array)($data['statuses']??array());if(!$statuses)return array('status'=>'not_found');usort($statuses,static function($a,$b){$a=(array)$a;$b=(array)$b;return strcmp((string)($b['createdProvider']??$b['created']??''),(string)($a['createdProvider']??$a['created']??''));});$latest=(array)$statuses[0];$label=(string)($latest['providerName']??$latest['name']??$latest['status']??'');$when=(string)($latest['createdProvider']??$latest['created']??'');$info=(array)($data['orderInfo']??array());
        return array('status'=>'ready','shipment'=>array('carrier'=>'ApiShip','carrier_code'=>$this->code(),'tracking_number'=>$number,'client_number'=>$number,'external_order_id'=>$external_order_id,'status'=>TrackingStatus::fromText($label),'status_label'=>$label,'updated_at'=>$when,'tracking_url'=>(string)($info['trackingUrl']??'')),'events'=>array_map(function($row){$row=(array)$row;$label=(string)($row['providerName']??$row['name']??'');return array('status'=>TrackingStatus::fromText($label),'label'=>$label,'date'=>(string)($row['createdProvider']??$row['created']??''),'location'=>'');},array_slice($statuses,0,20)));
    }
    public function trackingUrl(string $number):string{return '';}
}
