<?php

namespace App\Services;

use App\OrderPackage;
use App\Traits\ServiceAppAop;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;

class LogisticYDService
{
    use ServiceAppAop;

    private $app_key;
    private $app_secret;
    private $url;


    /**
     * 批量订阅接口
     * @param $logistic_numbers array
     * @return mixed
     */
    public function registerApi(array $logistic_numbers)
    {
        $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
        $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
        $this->url = config('api_logistic.YD.prod.register.url');
        $sender = [
            "address" => "上海市松江区泗泾镇泗砖公路351号",
            "city" => "上海市",
            "county" => "松江区",
            "name" => "施尧",
            "phone" => '13761413262',
            "province" => "上海市"
        ];
        $body = [
            "orders" => [],
        ];
        $order_packages = OrderPackage::query()
            ->with('order')
            ->whereIn('logistic_number', $logistic_numbers)->get();
        foreach ($order_packages as $order_package) {
            $order = $order_package->order;
            $body['orders'][] = [
                'orderid' => $order->client_code,
                "mailno" => $order_package->logistic_number,
                "receiver" => [
                    "address" => $order->address,
                    "city" => $order->city,
                    "county" => $order->district,
                    "name" => $order->consignee_name,
                    "phone" => $order->consignee_phone,
                    "province" => $order->province
                ],
                "sender" => $sender
            ];
        }
        $json_body = json_encode($body, JSON_UNESCAPED_UNICODE);
        $sign = md5($json_body . '_' . $this->app_secret);
        $headers = [
            'app-key' => $this->app_key,
            'sign' => $sign,
            'req-time' => now()->timestamp,
            "Content-Type" => "application/json"
        ];
        $response = Http::withHeaders($headers)->withBody($json_body, 'application/json')->post($this->url);
        return json_decode($response);
    }

    public function query($logistic_number)
    {
        $this->app_key = config('api_logistic.YD.prod.app-key', '999999');
        $this->app_secret = config('api_logistic.YD.prod.app-secret', '04d4ad40eeec11e9bad2d962f53dda9d');
        $this->url = config('api_logistic.YD.prod.search.url');
        $body = [
            "mailno" => $logistic_number
        ];
        $sign = md5(json_encode($body, JSON_UNESCAPED_UNICODE) . '_' . $this->app_secret);
        $headers = [
            'app-key' => $this->app_key,
            'sign' => $sign,
            'req-time' => now()->timestamp,
            "Content-Type" => "application/json"
        ];
        $response = Http::withHeaders($headers)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json')->post($this->url);
        return json_decode($response->body());
    }

    public function format($nativeResponse)
    {
        if ($nativeResponse->code != '0000' || $nativeResponse->data->result=="false") {
            return [];
        } else {
            $nativeData = $nativeResponse->data;
            $result['logistic_number'] = $nativeData->mailno;
            $nativeRoutes = $nativeData->steps;
            if (!empty($nativeRoutes)) {
                $lastNativeRoute = $nativeRoutes[count($nativeRoutes) - 1];
                $result['status'] = $this->getStatus($nativeData);
                if ($result['status'] == '已收件') {
                    $result['received_at'] = $lastNativeRoute->time;
                }
                $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
                $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
                $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
                $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->time : null);
                $result['exception_type'] = $exceptionData['exception_type'];
                $result['exception'] = $exceptionData['exception'];

            } else {
                $result['status'] = null;
                $result['transfer_status'] = [];
            }

            if (!array_key_exists('status', $result)) {
                $result['status'] = null;
                $result['transfer_status'] = [];
            }
            //如果没有发现额外的异常，且查询到物流轨迹，将异常置为无
            if (!array_key_exists('exception', $result)
                && !array_key_exists('exception_type', $result)
                && array_key_exists('transfer_status', $result)
            ) {
                $result['exception_type'] = '无';
                $result['exception'] = '否';
            }
            return $result;
        }
    }

    /**
     * @param $nativeData
     * @return string
     */
    private function getStatus($nativeData): string
    {
        $status = null;
        switch ($nativeData->status) {
            case 'GOT':
                $status = '已揽收';
                break;
            case 'TRANSIT':
                $status = '在途';
                break;
            case 'SIGNED':
                $status = '已收件';
                break;
            case 'RETURN':
                $status = '返回中';
                break;
            case 'SIGNFAIL':
                $status = '无';
                break;
            default:
                $status = '无';
        }
        return $status;
    }

    /**
     * @param $nativeRoutes
     * @return array
     */
    private function getTransferStatus($nativeRoutes): array
    {
        $transferStatus = [];
        foreach ($nativeRoutes as $nativeRoute) {
            $item = [];
            $item['accept_time'] = $nativeRoute->time;
            $item['accept_address'] = $nativeRoute->description;
            $item['remark'] = "";
            $transferStatus[] = $item;
        }
        return $transferStatus;
    }
}
