<?php

namespace App\Services\WayBill\JingDong;

use App\Events\CreateLogisticEvent;
use App\Http\Enum\BusinessOrderShippingStatus;
use App\Models\BusinessOrder;
use App\Models\BusinessOrderItem;
use App\Models\GoodsSku;
use App\Models\ShopSender;
use App\Models\ShopShip;
use App\Models\Waybill;
use App\Services\Business\KuaiTuanTuan\FaceSheet;

class WayBillService
{
    public $orders;
    public $objectId;
    public $adminUser;
    // 标准模板
    public $templateUrl = 'https://template-content.jd.com/template-oss?tempCode=jdkd76x130';
    // 标准模板
    public $customerTempUrl = "https://template-content.jd.com/template-open?templateCode=customerInfo";

    // 时效类型
    public $timedDeliveryCode;

    /**
     * 新版京东打印-下单
     * @return array
     */
    public function getWayBillContents()
    {
        // 已下单过的订单不再下单
        $contents = [];
        $this->adminUser = auth('api')->user();
        $jingDongService = new JingDongService();
        foreach ($this->orders as $shopId => $order) {
            // 订单取消的情况暂不处理
            $shopSend = $this->getShopSend($shopId);
            foreach ($order as $item) {
                [$sender, $orderInfo, $senderConfig] = $this->prepareRequest($item, $shopSend);
                $waybill = $this->saveWayBill($item, $shopSend, $senderConfig);
                if (empty($waybill->waybill_code)) {
                    $resp = $jingDongService->createOrder($waybill);
                    if (isset($resp['waybillNo'])) {
                        $waybill->status = Waybill::$STATUS_CREATE_WAYBILL_CODE;
                        $waybill->waybill_code = $resp['waybillNo'];
                        $waybill->save();

                        BusinessOrder::query()->where('order_sn', $waybill->order_sn)->update(["shipping_status" => BusinessOrderShippingStatus::SHIPPED]);
                        //物流发货
                        event(new CreateLogisticEvent($waybill->shop_id, $waybill->order_sn, $waybill->waybill_code));
                    }
                }
                //返回面单待打印数据
                if (empty($waybill->encryptedData)) {
                    // 延时0.5秒  防止订单查询不到
                    usleep(0.5 * 1000000);
                    $resp = $jingDongService->pullData($waybill);
                    if (!empty($resp[0]['perPrintData'])) {
                        $waybill->status = Waybill::$STATUS_CREATE_WAYBILL_ENCRYPTED_DATA;
                        $waybill->templateUrl = $this->templateUrl;
                        $waybill->customer_temp_url = $this->customerTempUrl;
                        $waybill->customer_temp_data = json_encode(['productInfo' => $item['productInfo']], 256);
                        $waybill->encryptedData = $resp[0]['perPrintData'];
                        $waybill->save();
                    }
                }
                $contents[$item['id']] = $waybill;

            }
        }

        return $contents;
    }

    public function getDocumentsAndOrderIds($contents)
    {
        // 打印单,根据商品排序
        $items = [];
        foreach ($contents as $docId => $content) {
            foreach ($content['items'] as $item) {
                if ($item['is_single']) {
                    $items[$item['external_sku_id']][] = $docId;
                }
            }
        }
        ksort($items);
        $documents = $orderIds = $hasIds = [];
        foreach ($items as $docIds) {
            $docIds = array_unique($docIds);
            $docIds = array_diff($docIds, $hasIds);
            $hasIds = array_merge($hasIds, $docIds);
            foreach ($docIds as $docId) {
                $orderIds[] = $contents[$docId]['order_id'];
                $documents[] = $contents[$docId];
            }
        }

        return [$documents, $orderIds];
    }

    private function saveWayBill($order, $shopShip, $senderConfig)
    {
        $waybill = Waybill::query()->firstOrNew(
            ['order_sn' => $order['order_sn']]
        );

        $waybill->shop_id = $order['shop_id'];
        $waybill->object_id = $this->objectId;

        $waybill->sender_country = $senderConfig['country'];
        $waybill->sender_province = $senderConfig['province'];
        $waybill->sender_city = $senderConfig['city'];
        $waybill->sender_district = $senderConfig['district'];
        $waybill->sender_detail = $senderConfig['detail'];
        $waybill->sender_name = $senderConfig['name'];
        $waybill->sender_mobile = (int)$senderConfig['mobile'];

        $waybill->recipient_province = $order['recipient_province'];
        $waybill->recipient_city = $order['recipient_city'];
        $waybill->recipient_district = $order['recipient_district'];
        $waybill->recipient_detail = $order['recipient_detail'];
        $waybill->recipient_name = $order['recipient_name'];
        $waybill->recipient_mobile = $order['recipient_mobile'];

        $waybill->user_id = $this->adminUser->id ?? 0;
        $waybill->wp_code = $senderConfig['wp_code'];
        $waybill->order_sn = $order['order_sn'];
        $waybill->order_id = $order['id'];
        $waybill->participate_no = $order['participate_no'] ?? 0;
        $waybill->note = $order['note'];
        $waybill->items = json_encode($order['items'], 256);
        $waybill->save();
        return $waybill;
    }

    private function getTimedDelivery($order)
    {
        $this->timedDeliveryCode = Waybill::$BUSINESS_EXPRESS_CODE;
        $address = [
            '辽宁省' => [],
            '吉林省' => [],
            '黑龙江省' => [],
            '甘肃省' => [],
            '海南省' => [],
            '宁夏回族自治区' => [
                '银川市', '石嘴山市', '吴忠市', '固原市'
            ],
            '青海省' => [
                '西宁市', '海东市', '海北藏族自治州', '黄南藏族自治州', '海南藏族自治州', '玉树藏族自治州'
            ],
        ];
        if (isset($address[$order['recipient_province']])) {
            if (empty($address[$order['recipient_province']])) {
                $this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
            }
            if ($address[$order['recipient_province']] && in_array($order['recipient_city'], $address[$order['recipient_province']], true)) {
                $this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
            }
        }
    }

    private function prepareRequest($order, $shopSend)
    {
        $this->setObjectId();

        $items = [];
        foreach ($order['items'] as $item) {
            $items[] = [
                'name' => $item['name'],
                'count' => $item['count'],
            ];
        }

        if (empty($shopSend)) {
            abort(404, '发货人信息未匹配');
        }
        $senderConfig = $shopSend;
        $sender = [
            'address' => [
                'city' => $senderConfig['city'],
                'country' => $senderConfig['country'],
                'detail' => $senderConfig['detail'],
                'district' => $senderConfig['district'],
                'province' => $senderConfig['province'],
            ],
            'name' => $senderConfig['name'],
            'mobile' => $senderConfig['mobile'],
        ];

        $orderInfo = [
            'object_id' => $this->objectId,
            'order_info' => [
                'order_channels_type' => 'PDD',
                'trade_order_list' => [$order['order_sn']],
            ],
            'package_info' => [
                'items' => $items,
            ],
            'recipient' => [
                'address' => [
                    'city' => $order['recipient_city'],
                    'detail' => $order['recipient_detail'],
                    'district' => $order['recipient_district'],
                    'province' => $order['recipient_province'],
                ],
                'name' => $order['recipient_name'],
                'mobile' => $order['recipient_mobile'],
            ],
            'template_url' => $this->templateUrl,
        ];

        return [$sender, $orderInfo, $senderConfig];
    }

    public function setObjectId()
    {
        $this->objectId = date('YmdHis') . str_pad(mt_rand(1, 9999999), 7, '0', STR_PAD_LEFT);

        return $this;
    }

    public function setOrders($orders)
    {
        $orders = $orders->toArray();
        // 订单拆分组合
        foreach ($orders as $order) {
            if ($order['shipping_status'] != BusinessOrderShippingStatus::UNSHIP) {
                continue;
            }
            if ($order['cancel_status'] == 1) {
                continue;
            }
            $info = [
                'id' => $order['id'],
                'shop_id' => $order['shop_id'],
                'order_sn' => $order['order_sn'],
                'recipient_province' => $order['receiver_address_province'],
                'recipient_city' => $order['receiver_address_city'],
                'recipient_district' => $order['receiver_address_district'],
                'recipient_detail' => $order['receiver_address_detail'],
                'recipient_name' => $order['receiver_name'],
                'recipient_mobile' => $order['receiver_mobile'],
                'participate_no' => $order['is_supplier'] ? $order['participate_no'] : $order['supply_participate_no'],
                'note' => $order['business_note'] ? $order['business_note'] . ',' . $order['buyer_memo'] : $order['buyer_memo'],
                'items' => []
            ];
            $note = "";
            foreach ($order['items'] as $item) {
                $count = $item['goods_number'] - $item['already_cancel_number'];
                $info['items'][] = [
                    'is_single' => true,
                    'should_print' => true,
                    'name' => $item['goods_name'],
                    'count' => $count,
                    'external_sku_id' => $item['external_sku_id'],
                ];
                $note .= $item['goods_name'] . " " . $count . "件,";
            }
            $info['productInfo'] = $note;
            $this->orders[$order['shop_id']][] = $info;
        }

        return $this;
    }

    private function getShopSend($shopId)
    {
        return ShopSender::query()
            ->where('shop_id', $shopId)
            ->where('status', 1)->orderByDesc('sort')
            ->first();
    }

    private function getShopShip($shopId)
    {
        return ShopShip::query()
            ->select(['id', 'shop_id', 'access_token', 'owner_id'])
            ->where('shop_id', $shopId)
            ->with([
                'senders' => function ($query) {
                    $query->where('status', 1)->orderBy('sort');
                }
            ])
            ->first();
    }
}
