<?php

namespace app\common\shipping;

use GuzzleHttp\Client;
use Ecpay\Sdk\Factories\Factory;
use Ecpay\Sdk\Services\CheckMacValueService;

use app\common\shipping\Ishipping;

use think\facade\Db;
use think\facade\Log;

//實作物流串接介面
class EcpayShipping implements Ishipping
{

    private $api_url;
    private $MerchantId;
    private $HashIv;
    private $HashKey;
    private $SenderName;
    private $SenderPhone;

    public function __construct()
    {
        $shipping = Db::name('shipping')
            ->where('shipping_code', 'ecpay')
            ->find();

        $config = json_decode($shipping['shipping_config'], true);

        if ($shipping['is_test'] == 0) {
            $this->api_url = 'https://logistics-stage.ecpay.com.tw';
            $this->MerchantId = '2000933';
            $this->HashIv = 'h1ONHk4P4yqbl5LK';
            $this->HashKey = 'XBERn1YOvpM9nfZc';
            $this->SenderName = isset($config['SenderName']) ? $config['SenderName'] : '測試人員';
            $this->SenderPhone = isset($config['SenderPhone']) ? $config['SenderPhone'] : '0900000001';
        } else {
            if (empty($config['MerchantId']) || empty($config['HashIv']) || empty($config['HashKey'])) {
                throw new \Exception('請先設定綠界物流參數');
            }
            $this->api_url = 'https://logistics.ecpay.com.tw';
            $this->MerchantId = $config['MerchantId'];
            $this->HashIv = $config['HashIv'];
            $this->HashKey = $config['HashKey'];
            $this->SenderName = isset($config['SenderName']) ? $config['SenderName'] : getConfigValue('service_company');
            $this->SenderPhone = isset($config['SenderPhone']) ? $config['SenderPhone'] : getConfigValue('service_phone');
        }
    }

    public function request($order)
    {
        $subType['1'] = 'UNIMARTC2C';
        $subType['2'] = 'FAMIC2C';
        $subType['3'] = 'HILIFEC2C';
        $subType['4'] = 'OKMARTC2C';

        $goods_list = '';
        foreach ($order['goods_list'] as $goods) {
            $goods_list .= $goods['goods_name'] . "#";
            //如果$goods_list結尾是#，則去掉
            if (substr($goods_list, -1) == '#') {
                $goods_list = substr($goods_list, 0, -1);
            }
        }


        $logistics = json_decode($order['address'], true);


        // 綠界物流串接
        $factory = new Factory([
            'hashKey' => $this->HashKey,
            'hashIv' => $this->HashIv,
            'hashMethod' => 'md5',
        ]);

        $ecService = $factory->create('PostWithCmvStrResponseService');

        $shipping_data = [
            'MerchantID' => $this->MerchantId,
            'LogisticsType' => 'CVS',
            'MerchantTradeNo' => $order['order_sn'],
            'MerchantTradeDate' => date('Y/m/d H:i:s'),
            'LogisticsSubType' => $subType[$logistics['type']],
            'GoodsAmount' => $order['order_amount'],
            'CollectionAmount' => $order['order_amount'],
            'IsCollection' => $order['pay_id'] == 0 ? 'Y' : 'N',
            'GoodsName' => $goods_list,
            'SenderName' => $this->SenderName,
            'SenderPhone' => $this->SenderPhone,
            'SenderCellPhone' => $this->SenderPhone,
            'ReceiverName' => $order['consignee'],
            // 'ReceiverPhone' => $user_info['mobile_phone'],
            'ReceiverCellPhone' => $order['mobile'],
            'ReceiverStoreID' => $logistics['store_id'],
            'ServerReplyURL' => getUrl() . '/appapi/v1/shipping/response/shippingcode/ecpay/',
        ];

        $action = $this->api_url . '/Express/Create';

        $rtn = $ecService->post($shipping_data, $action);
        $rtn = explode("|", $rtn['body']);

        if ($rtn[0] === '1') {
            parse_str($rtn[1], $data);
            //更新訂單資料
            try {
                Db::name('order_info')
                    ->where('order_sn', $order['order_sn'])
                    ->update([
                        'shipping_status' => 3,
                        'shipping_token' => $data['AllPayLogisticsID'],
                        'shipping_data' => json_encode($data)
                    ]);

                // $order = Db::name('order_info')
                //     ->where('order_sn', $order['order_sn'])
                //     ->find();

                //更新訂單操縱紀錄
                // $order_action = [
                //     'order_id' => $order['order_id'],
                //     'action_user' => '綠界科技',
                //     'order_status' => $order['order_status'],
                //     'shipping_status' => $order['shipping_status'],
                //     'pay_status' => $order['pay_status'],
                //     'action_note' => '綠界物流：' . $data['LogisticsSubType'] . '，' . $data['RtnMsg'],
                //     'log_time' => strtotime($data['UpdateStatusDate'])
                // ];
                // Db::name('order_action')->insert($order_action);

            } catch (\Exception $e) {
                return ['code' => 500, 'msg' => $e->getMessage()];
            }

            return ['code' => 200, 'msg' => '更新成功'];
        } else {
            return ['code' => 500, 'msg' => $rtn[1]];
        }
    }

    public function response($data)
    {
        Log::write('綠界物流回傳：' . json_encode($data));
        //判斷是否為綠界回傳資料
        if (!isset($data['AllPayLogisticsID'])) {
            return FALSE;
        }

        //TODO: 檢查碼驗證
        //建立checkMacValueService物件
        // $checkMacValueService  = new CheckMacValueService($this->HashKey, $this->HashIv, 'md5');
        //檢查碼驗證
        // $checkMacValue = $checkMacValueService->generate($data);

        // if($checkMacValue != $data['CheckMacValue']){
        //     return FALSE;
        // }

        $code = 201;
        $message = '';

        $order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();

        switch ($data['LogisticsSubType']) {
            case 'UNIMARTC2C':
                switch ($data['RtnCode']) {
                    case '300':
                        $update_data = [
                            'shipping_status' => 3,
                        ];
                        break;
                    case '2073':
                        //物流已達取件門市，訂單完成
                        $update_data = [
                            'shipping_status' => 7,
                        ];
                        break;
                    case '2067':
                        //物流已領取，訂單完成
                        $update_data = [
                            'shipping_status' => 2,
                            'order_status' => 7,
                            'pay_status' => 2,
                        ];
                        $code = 200;
                        break;
                    case '2074':
                        //物流未領，訂單取消
                        $update_data = [
                            'shipping_status' => 4,
                            'order_status' => 6,
                            'pay_status' => 0,
                        ];

                        //判斷是否為SlashCard產品，並且為貨到付款
                        $order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
                        $is_main = Db::name('order_goods')
                            ->where('order_id', $order['order_id'])
                            ->where('goods_id', 1)
                            ->find();

                        if ($is_main && $order['pay_id'] == 0) {
                            //將slashcard訂單取消
                            $rtn = \app\service\Card::cancelUser([
                                'order_sn' => $order['order_sn'],
                                'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
                            ]);

                            if ($rtn['code'] != 200) {
                                // 扣除點數失敗
                            }
                        }

                        break;
                    default:
                        $update_data = [
                            'shipping_status' => 1,
                        ];
                        break;
                }
                break;
            case 'FAMIC2C':
                switch ($data['RtnCode']) {
                    case '3032':
                        //至超商寄貨
                        $update_data = [
                            'shipping_status' => 5,
                            'order_status' => $order['order_status'],
                            'pay_status' => $order['pay_status'],
                        ];
                        break;
                    case '3018':
                        //物流已達取件門市，訂單完成
                        $update_data = [
                            'shipping_status' => 7,
                        ];
                        break;

                    case '3022':
                        $update_data = [
                            'shipping_status' => 2,
                            'order_status' => 7,
                            'pay_status' => 2,
                        ];
                        $code = 200;
                        break;
                    case '3020':
                        //物流未領，訂單取消
                        $update_data = [
                            'shipping_status' => 4,
                            'order_status' => 6,
                            'pay_status' => 0,
                        ];
                        //判斷是否為SlashCard產品，並且為貨到付款
                        $order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
                        $is_main = Db::name('order_goods')
                            ->where('order_id', $order['order_id'])
                            ->where('goods_id', 1)
                            ->find();

                        if ($is_main && $order['pay_id'] == 0) {
                            //將slashcard訂單取消
                            $rtn = \app\service\Card::cancelUser([
                                'order_sn' => $order['order_sn'],
                                'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
                            ]);

                            if ($rtn['code'] != 200) {
                                // 扣除點數失敗
                            }
                        }

                        break;
                    default:
                        $update_data = [
                            'shipping_status' => 1,
                            'order_status' => $order['order_status'],
                            'pay_status' => $order['pay_status'],
                        ];

                        break;
                }
                break;
            case 'HILIFEC2C':
                switch ($data['RtnCode']) {
                    case '2001':
                        //物流單成立
                        $update_data = [
                            'shipping_status' => 3,
                        ];
                        break;
                    case '3018':
                    case '2063':
                        //物流已達取件門市，訂單完成
                        $update_data = [
                            'shipping_status' => 7,
                        ];
                        break;

                    case '3022':
                    case '2067':
                        $update_data = [
                            'shipping_status' => 2,
                            'order_status' => 7,
                            'pay_status' => 2,
                        ];
                        $code = 200;
                        break;
                    case '3020':
                    case '2074':
                        //物流未領，訂單取消
                        $update_data = [
                            'shipping_status' => 4,
                            'order_status' => 6,
                            'pay_status' => 0,
                        ];
                        //判斷是否為SlashCard產品，並且為貨到付款
                        $order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
                        $is_main = Db::name('order_goods')
                            ->where('order_id', $order['order_id'])
                            ->where('goods_id', 1)
                            ->find();

                        if ($is_main && $order['pay_id'] == 0) {
                            //將slashcard訂單取消
                            $rtn = \app\service\Card::cancelUser([
                                'order_sn' => $order['order_sn'],
                                'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
                            ]);

                            if ($rtn['code'] != 200) {
                                // 扣除點數失敗
                            }
                        }

                        break;

                    default:
                        $update_data = [
                            'shipping_status' => 1,
                            'order_status' => $order['order_status'],
                            'pay_status' => $order['pay_status'],
                        ];

                        break;
                }
                break;
            case 'OKMARTC2C':
                switch ($data['RtnCode']) {
                    case '300':
                        $update_data = [
                            'shipping_status' => 3,
                        ];
                        break;
                    case '2073':
                        //物流已達取件門市，訂單完成
                        $update_data = [
                            'shipping_status' => 7,
                        ];
                        break;
                    case '3022':
                        $update_data = [
                            'shipping_status' => 2,
                            'order_status' => 7,
                            'pay_status' => 2,
                        ];
                        $code = 200;
                        break;
                    case '3032':
                        //至超商寄貨
                        $update_data = [
                            'shipping_status' => 1, //已發貨
                            'order_status' => $order['order_status'],
                            'pay_status' => $order['pay_status'],
                        ];
                        break;
                    case '2074':
                        //物流未領，訂單取消
                        $update_data = [
                            'shipping_status' => 4,
                            'order_status' => 6,
                            'pay_status' => 0,
                        ];
                        //判斷是否為SlashCard產品，並且為貨到付款
                        $order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
                        $is_main = Db::name('order_goods')
                            ->where('order_id', $order['order_id'])
                            ->where('goods_id', 1)
                            ->find();

                        if ($is_main && $order['pay_id'] == 0) {
                            //將slashcard訂單取消
                            $rtn = \app\service\Card::cancelUser([
                                'order_sn' => $order['order_sn'],
                                'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
                            ]);

                            if ($rtn['code'] != 200) {
                                // 扣除點數失敗
                            }
                        }

                        break;
                    default:
                        $update_data = [
                            'shipping_status' => 1,
                            'order_status' => $order['order_status'],
                            'pay_status' => $order['pay_status'],
                        ];
                        break;
                }
                break;
            default:
                $code = 500;
                break;
        }
        try {
            //新增物流紀錄到order_shipping
            $shipping_data = [
                'order_id' => Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->value('order_id'),
                'code' => $data['RtnCode'],
                'note' => $data['RtnMsg'],
                'create_time' => strtotime($data['UpdateStatusDate']),
            ];

            Db::name('order_shipping')->insert($shipping_data);

            //更新訂單資料
            if (isset($update_data)) {
                Db::name('order_info')
                    ->where('order_sn', $data['MerchantTradeNo'])
                    ->update($update_data);
            }

            //更新訂單操作記錄
            $order_info = Db::name('order_info')
                ->where('order_sn', $data['MerchantTradeNo'])
                ->find();

            Db::name('order_action')
                ->insert(
                    [
                        'order_id' => $order_info['order_id'],
                        'action_user' => '綠界科技',
                        'order_status' => $order_info['order_status'],
                        'shipping_status' => $order_info['shipping_status'],
                        'pay_status' => $order_info['pay_status'],
                        'action_note' => '綠界物流：' . $data['LogisticsSubType'] . '，' . $data['RtnMsg'],
                        'log_time' => strtotime($data['UpdateStatusDate'])
                    ]
                );
        } catch (\Exception $e) {
            $code = 500;
            $message = $e->getMessage();
        }

        $rtn = [
            'code' => $code,
            'shippingcode' => 'ecpay',
            'msg' => $message,
            'order_sn' => $data['MerchantTradeNo'],
        ];

        return $rtn;
    }

    public function map($params)
    {
        // 綠界物流地圖串接
        $factory = new Factory([
            'hashKey' => $this->HashKey,
            'hashIv' => $this->HashIv,
            'hashMethod' => 'md5',
        ]);

        $formService = $factory->create('ReturnSubmitFormWithCmvService');

        $input = [
            'MerchantID' => $this->MerchantId,
            'LogisticsType' => 'CVS',
            'ServerReplyURL' => getUrl() . '/appapi/v1/shipping/mapresponse/shippingcode/ecpay/',
        ];

        $input = array_merge($input, $params);
        $action = $this->api_url . '/Express/map';
        return $formService->generate($input, $action);
    }

    public function mapResponse($data)
    {
        //將LogisticsSubType轉換成數字
        switch ($data['LogisticsSubType']) {
            case 'UNIMARTC2C':
                $data['LogisticsSubType'] = 1;
                break;
            case 'FAMIC2C':
                $data['LogisticsSubType'] = 2;
                break;
            case 'HILIFEC2C':
                $data['LogisticsSubType'] = 3;
                break;
            case 'OKMARTC2C':
                $data['LogisticsSubType'] = 4;
                break;
            default:
                return FALSE;
                break;
        }

        $iData = [
            'user_id' => getIdBySsoId($data['ExtraData']),
            'type' => $data['LogisticsSubType'],
            'store_id' => $data['CVSStoreID'],
            'store_name' => $data['CVSStoreName'],
            'store_address' => $data['CVSAddress'],
            'store_tel' => $data['CVSTelephone'],
            'is_default' => 1,
        ];

        //將$data寫入user_cvs資料庫

        $is_exist = Db::name('user_cvs')
            ->where('store_id', $data['CVSStoreID'])
            ->where('user_id', getIdBySsoId($data['ExtraData']))
            ->count();

        try {
            //將所有的is_default設為0       
            Db::name('user_cvs')
                ->where('user_id', getIdBySsoId($data['ExtraData']))
                ->update(['is_default' => 0]);

            if (!$is_exist) {
                Db::name('user_cvs')->insert($iData);
            } else {
                //將該筆資料的is_default設為1
                Db::name('user_cvs')
                    ->where('user_id', getIdBySsoId($data['ExtraData']))
                    ->where('store_id', $data['CVSStoreID'])
                    ->update(['is_default' => 1]);
            }
        } catch (\Exception $e) {
            return FALSE;
        }

        // $result['redirect_url'] = 'http://localhost:5173/m/order/shipping?is_return=1';
        $result['redirect_url'] = getUrl() . '/m/order/shipping?is_return=1';

        return $result;
    }

    public function printLabel($params)
    {

        $factory = new Factory([
            'hashKey' => $this->HashKey,
            'hashIv' => $this->HashIv,
            'hashMethod' => 'md5',
        ]);

        $formService = $factory->create('AutoSubmitFormWithCmvService');

        $input = [
            'MerchantID' => $this->MerchantId,
            'PlatformID' => '',
        ];

        $input = array_merge($input, $params);

        switch ($params['type']) {
            case 'UNIMARTC2C':
                $action = $this->api_url . '/Express/PrintUniMartC2COrderInfo';
                break;
            case 'FAMIC2C':
                $action = $this->api_url . '/Express/PrintFAMIC2COrderInfo';
                break;
            case 'HILIFEC2C':
                $action = $this->api_url . '/Express/PrintHiLifeC2COrderInfo';
                break;
            case 'OKMARTC2C':
                $action = $this->api_url . '/Express/PrintOKMARTC2COrderInfo';
                break;
        }
        return $formService->generate($input, $action);
    }
}
