<?php


namespace App\Http\Controllers\api\thirdPart\jianshang;


use App\Http\Controllers\Controller;
use App\Logistic;
use App\QualityLabel;
use App\RejectedBill;
use App\RejectedBillItem;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Zttp\Zttp;
use Zttp\ZttpResponse;

class RejectedController extends Controller
{
    function sendRejected($rejected){
        $amount = $rejected['amount'] ?? '';
        $created_at = $rejected['created_at'] ?? '';
        $fee_collected = $rejected['fee_collected'] ?? '';
        $goods_barcode = $rejected['barcode_goods'] ?? '';
        $goods_name = $rejected['name_goods'] ?? '';
        $logistic_name_return = Logistic::nameById($rejected['id_logistic_return']);
        $logistic_number = $rejected['logistic_number'] ?? '';
        $logistic_number_return = $rejected['logistic_number_return'] ?? '';
        $order_number = $rejected['order_number'] ?? '';
        $quality_label = QualityLabel::where('id',$rejected['id_quality_label'])->first();
        $quality_label = $quality_label?$quality_label['name']:'';
        $sender_mobile = $rejected['mobile_sender'] ?? '';
        $sender_name = $rejected['sender'] ?? '';
        $json = $this->packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
            $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
            $quality_label,$sender_mobile,$sender_name);
        if(!$json){
            app('LogService')->log(__METHOD__,'error'.'_'.$logistic_number_return,"没有返回");
            return false;
        }
        if(!$json['success']){
            app('LogService')->log(__METHOD__,'error'.'_'.$logistic_number_return,"返回错误：".json_encode($json));
            return false;
        }else{
            app('LogService')->log(__METHOD__,'JianshangResponse'.'_'.$logistic_number_return,json_encode($json));
        }
        return $json;
    }


    function sendRejectedByApi(Request $request){
        $amount = $request->input('amount') ?? '';
        $created_at = $request->input('created_at') ?? '';
        $fee_collected = $request->input('fee_collected') ?? '';
        $goods_barcode = $request->input('goods_barcode') ?? '';
        $goods_name = $request->input('goods_name') ?? '';
        $logistic_name_return = $request->input('logistic_name_return') ?? '';
        $logistic_number = $request->input('logistic_number') ?? '';
        $logistic_number_return = $request->input('logistic_number_return') ?? '';
        $order_number = $request->input('order_number') ?? '';
        $quality_label = $request->input('quality_label') ?? '';
        $sender_mobile = $request->input('sender_mobile') ?? '';
        $sender_name = $request->input('sender_name') ?? '';
        $json = $this->packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
            $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
            $quality_label,$sender_mobile,$sender_name);
        if(!$json)return ['success'=>'false','fail_info'=>'没有JSON回复'];
        if(!$json['success']){return $this->apiError(__METHOD__,"返回错误：".json_encode($json));}
        return $json;
    }
    private function packSendToRemote($amount,$created_at,$fee_collected,$goods_barcode,
                                      $goods_name,$logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
                                      $quality_label,$sender_mobile,$sender_name){
        if(env('api_faking')){
            app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'API FAKING');
            return false;
        }
        $data="{\"amount\":\"$amount\", \"created_at\":\"$created_at\", \"fee_collected\":\"$fee_collected\",
        \"goods_barcode\":\"$goods_barcode\", \"goods_name\":\"$goods_name\", \"logistic_name_return\":\"$logistic_name_return\",
         \"logistic_number\":\"$logistic_number\", \"logistic_number_return\":\"$logistic_number_return\",
         \"order_number\":\"$order_number\", \"quality_label\":\"$quality_label\", \"sender_mobile\":\"$sender_mobile\", \"sender_name\":\"$sender_name\"}";
        $sortParamsAndMd5=function(Array $params,$timestamp,$nonce,$signKey){
            $params=new Collection($params);
            $params=$params->sortKeys();
            $str='';
            $params->each(function($param,$key)use(&$str){
                $val=trim($param);
                if($val){
                    $str .= $key.$val;
                }
            });
            return strtolower(md5($str.$timestamp.$nonce.$signKey));
        };
        $timestamp=intval(microtime(true)*1000);
        $nonce=md5(microtime(true));
        $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));
        $url=config('api.url_rejected_send_jianshang');
        $response=Zttp::withHeaders([
            'sign'=>$sign,
            'nonce'=>$nonce,
            'timestamp'=>$timestamp,
            'Content-Type'=>'application/json'
        ])->post($url,json_decode($data,true));
        app('LogService')->log(__METHOD__,__FUNCTION__,$data);
        if(!$response){
            app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'回复异常：'.$response->body());
            return false;
        }
        if(!$response->json()){
            app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,'json为空：'.$response->body());
            return false;
        }
        return $response->json();
    }

    function sendRejected2(array $rejected){
        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口，进入入口。退单号：{$rejected['logistic_number_return']}",Auth::user()['id']);
        $created_at = $rejected['created_at'] ?? '';
        $fee_collected = $rejected['fee_collected'] ?? '';
        $goodses=[];
        foreach ($rejected['goodses'] as $goods){
            $temGoods['amount']=$goods['amount'] ?? '';
            $temGoods['goods_barcode']=$goods['barcode_goods'] ?? '';
            $temGoods['goods_name']=$goods['name_goods'] ?? '';
            $temGoods['quality_label']=$goods['quality_label'] ?? '';
            $goodses[]=$temGoods;
        }
        $logistic_name_return = Logistic::nameById($rejected['id_logistic_return']);
        $logistic_number = $rejected['logistic_number'] ?? '';
        $logistic_number_return = $rejected['logistic_number_return'] ?? '';
        $order_number = $rejected['order_number'] ?? '';
        $sender_mobile = $rejected['mobile_sender'] ?? '';
        $sender_name = $rejected['sender'] ?? '';
        $json = $this->packSendToRemote2($created_at,$fee_collected,$goodses,
            $logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
            $sender_mobile,$sender_name);
        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口调度完成。退单号：{$rejected['logistic_number_return']}",Auth::user()['id']);
        if(!$json){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口异常，没有json返回。退单号：{$rejected['logistic_number_return']}",Auth::user()['id']);
            return 'fail';
        }else if(!isset($json['success'])||!$json['success']){
            if(strpos(json_encode($json),'已经接收过')!==false){
                return 'received';
            }
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口错误。退单号：{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
            return 'fail';
        }
        if(!$json['goodses_feedback']){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口返回不全，没有商品信息返回(goodses)。退单号：{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
        }
        if(!$json['logistic_number_return']){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口返回不全，没有退回快递单号。退单号：{$rejected['logistic_number_return']}。".json_encode($json),Auth::user()['id']);
        }
        $storable = (function ()use($json) {
            if(count($json['goodses_feedback'])==0)return false;
            foreach ($json['goodses_feedback'] as $goods){
                if(!$goods['storable']){
                    return false;
                }
            }
            return true;
        })();
        if(!$storable){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"发送笕尚接口提示，商品不可入库。退单号：{$rejected['logistic_number_return']}".json_encode($json),Auth::user()['id']);
            return 'none';
        }
        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"发送笕尚接口完成，可入库，待其未来推单。退单号：{$rejected['logistic_number_return']}".json_encode($json),Auth::user()['id']);
//        $this->markItemsIsLoaded($json);
        return 'storable';
    }

    private function packSendToRemote2($created_at,$fee_collected,$goodses,
                                      $logistic_name_return,$logistic_number,$logistic_number_return,$order_number,
                                      $sender_mobile,$sender_name){
        foreach ($goodses as $goods){
            asort($goods);
        }
        $goodses = json_encode($goodses);
        $data="{\"created_at\":\"$created_at\", \"fee_collected\":\"$fee_collected\",
         \"goodses\":$goodses,\"logistic_name_return\":\"$logistic_name_return\",
         \"logistic_number\":\"$logistic_number\", \"logistic_number_return\":\"$logistic_number_return\",
         \"order_number\":\"$order_number\", \"sender_mobile\":\"$sender_mobile\", \"sender_name\":\"$sender_name\"}";
        $sortParamsAndMd5=function(Array $params,$timestamp,$nonce,$signKey){
            $params=new Collection($params);
            $params=$params->sortKeys();
            $str='';
            $params->each(function($param,$key)use(&$str){
                if(is_array($param)){return;
//                    foreach ($param as &$paramValArr){
//                        foreach ($paramValArr as &$paramVal){
//                            $paramVal = trim($paramVal);
//                        }
//                    }
//                    $param=json_encode($param);
                }
                $val=trim($param);
                if($val){
                    $str .= $key.$val;
                }
            });
            $forSign = $str . $timestamp . $nonce . $signKey;
            return strtolower(md5($forSign));
        };
        $timestamp=intval(microtime(true)*1000);
        $nonce=md5(microtime(true));
        $sign=$sortParamsAndMd5(json_decode($data,true),$timestamp,$nonce,config('api.sign_key_rejected_send_jianshang'));
        app('LogService')->log(__METHOD__,'笕尚接口发送请求：',$data);
        $url=config('api.url_rejected_send_jianshang2');
        if(env('api_faking'))$url=url(config('api.fakingUrl_rejected_send_jianshang'));
        try{
            /** @var ZttpResponse $response */
            $response=Zttp::withHeaders([
                'sign'=>$sign,
                'nonce'=>$nonce,
                'timestamp'=>$timestamp,
                'Content-Type'=>'application/json'
            ])->post($url,json_decode($data,true));
        }catch (\Exception $e){
            app('LogService')->log(__METHOD__,'笕尚接口返回异常！！：',$e->getMessage().'||'.json_encode($data));
            $response=false;
        }
        if(!$response){
            app('LogService')->log(__METHOD__,'笕尚接口返回异常！！：',"沒有返回");
            return false;
        }
        app('LogService')->log(__METHOD__,'笕尚接口返回：',$response->body());
        return $response->json();
    }

    private function markItemsIsLoaded($json){
        $barcodes=[];
        foreach ($json['goodses_feedback'] as $goods){
            $barcodes[]=trim($goods['goods_barcode']);
        }
        $bill=RejectedBill::where('logistic_number_return',$json['logistic_number_return'])->first();
        $items=RejectedBillItem::where('id_rejected_bill',$bill['id'])->whereIn('barcode_goods',$barcodes)->get();
        $items->each(function(RejectedBillItem $item)use(&$json){
            foreach ($json['goodses_feedback'] as &$goods1){    //标记出有重复条码的商品，并且标记出其中是否同时有不能入库可和可以入库的
                $goods1['sameBarcode']=0;
                $goods1['hasUnStorable']=false;
                $goods1['hasStorable']=false;
                foreach ($json['goodses_feedback'] as &$goods2){
                    if($goods1['goods_barcode']==$goods2['goods_barcode']){
                        $goods1['sameBarcode']+=1;
                        if(!$goods2['storable']){
                            $goods1['hasUnStorable']=true;
                        }else{
                            $goods1['hasStorable']=true;
                        }
                    }
                }
            }
            foreach ($json['goodses_feedback'] as $goods){
                if($item['barcode_goods']==$goods['goods_barcode']){
                    $item['is_loaded'] = $goods['storable']==='true'|| $goods['storable']===true ? '已入库':'未入库';
                    if($goods['sameBarcode']>1){//如果该条码有不止一件，并且同时拥有入库和不入库的，就按品质标签来区分入库与否（因为回传不带是否正品消息，也没有ID）
                        if($goods['hasUnStorable']&&$goods['hasStorable']){
                            if($item['id_quality_label']==1){
                                $item['is_loaded'] ='已入库';
                            }else{
                                $item['is_loaded'] ='未入库';
                            }
                        }
                    }
                    $item->update();
                }
            }
        });
        return $bill;
    }
}
