<?php

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

use App\Events\WmsReceiveNewEvent;
use App\Http\Controllers\Controller;
use App\RejectedBill;
use App\RejectedBillItem;
use App\WMSReflectReceive;
use App\WMSReflectReceiveSku;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Zttp\Zttp;

class ReceiveController extends Controller
{

    /**
     * 收货任务下发
     */
    public function new_(Request $request)
    {
        ini_set('max_execution_time',2500);
        ini_set('memory_limit','1526M');
        $isNotAHugeList=(function()use(&$request){
            $requestArr=$request->input('request');
            return $requestArr&&isset($requestArr[0])&&isset($requestArr[0]['SKU_LIST'])
                &&count($request->input('request')[0]['SKU_LIST'])<=100;
        })();
        if($isNotAHugeList){
            $errors=$this->validatorForNew($request->all())->errors();
            if(count($errors)>0){
                app('LogService')->log(__METHOD__, 'error_body' . __FUNCTION__, json_encode($request->getContent()));
                (new Controller())->log(__METHOD__,'error_'.__FUNCTION__,'fields wrong, see Errors report please.'.'|'.json_encode($request).'|'.json_encode($errors));
                return response()->json(['response'=>['flag'=>'W','message'=>'fields wrong, see Errors report please.',
                    'errors'=>$errors]])
                    ->setEncodingOptions(JSON_UNESCAPED_UNICODE);
            }
        }
        $receiveInputs=$request->input('request');
        foreach ($receiveInputs as $receiveInput){
            $isRepeated=WMSReflectReceive::where('ASNNO',$receiveInput['ASNNO'])->first();
            if($isRepeated){
                (new Controller())->log(__METHOD__,'error_'.__FUNCTION__,'WMS下发时ASNNO重复'.'|'.json_encode($request));
                return response()->json(['response'=>['flag'=>'N','code'=>'6666','message'=>'ASNNO重复']])
                    ->setEncodingOptions(JSON_UNESCAPED_UNICODE);
            }
            $receive=new WMSReflectReceive($receiveInput);
            $receive->save();
            foreach ($receiveInput['SKU_LIST'] as $skuInput){
                $sku=new WMSReflectReceiveSku($skuInput);
                $receive->skus()->save($sku);
            }
            if(isset($receive['ASNREFERENCE3'])){
                if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"接收到WMS下发退货单号：{$receive['ASNREFERENCE3']}||".json_encode($request->all())."，准备进入事件WmsReceiveNewEvent",null);
                event(new WmsReceiveNewEvent($receive['ASNREFERENCE3'],$receive));
            }
        }
        return response()->json(['response'=>['flag'=>'Y','code'=>'0000','message'=>'正确接收']])
            ->setEncodingOptions(JSON_UNESCAPED_UNICODE);
    }
    protected function validatorForNew(array $data)
    {
        return Validator::make($data, [
            'request' => ['required', 'array', 'min:1'],
            'request.*.ASNNO' => ['required', 'string', 'max:191'],
            'request.*.WAREHOUSEID' => ['required', 'string', 'max:191'],
            'request.*.CUSTOMERID' => ['required', 'string', 'max:191'],
            'request.*.ASNTYPE' => ['nullable', 'string', 'max:191'],
            'request.*.ASNREFERENCE1' => ['nullable', 'string', 'max:191'],
            'request.*.ASNREFERENCE2' => ['nullable', 'string', 'max:191'],
            'request.*.ASNREFERENCE3' => ['nullable', 'string', 'max:191'],
            'request.*.ASNSTATUS' => ['nullable', 'string', 'max:191'],
            'request.*.NOTES' => ['nullable', 'string', 'max:191'],
            'request.*.USERDEFINE1' => ['nullable', 'string', 'max:191'],
            'request.*.USERDEFINE2' => ['nullable', 'string', 'max:191'],
            'request.*.USERDEFINE3' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST' => ['required', 'array', 'min:1'],
            'request.*.SKU_LIST.*.ASNLINENO' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.SKU' => ['required', 'string', 'max:191'],
            'request.*.SKU_LIST.*.ALTERNATE_SKU1' => ['required', 'string', 'max:191'],
            'request.*.SKU_LIST.*.SKUDESCRC' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.EXPECTEDQTY_EACH' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.UOM' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.LINESTATUS' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.LOTATT05' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.USERDEFINE4' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.USERDEFINE5' => ['nullable', 'string', 'max:191'],
            'request.*.SKU_LIST.*.USERDEFINE6' => ['nullable', 'string', 'max:191'],
        ],[],[
            'request.ASNNO' => 'ASNNO',
            'request.*.WAREHOUSEID' => 'WAREHOUSEID',
            'request.*.CUSTOMERID' => 'CUSTOMERID',
            'request.*.ASNTYPE' => 'ASNTYPE',
            'request.*.ASNREFERENCE1' => 'ASNREFERENCE1',
            'request.*.ASNREFERENCE2' => 'ASNREFERENCE2',
            'request.*.ASNREFERENCE3' => 'ASNREFERENCE3',
            'request.*.ASNSTATUS' => 'ASNSTATUS',
            'request.*.NOTES' => 'NOTES',
            'request.*.USERDEFINE1' => 'USERDEFINE1',
            'request.*.USERDEFINE2' => 'USERDEFINE2',
            'request.*.USERDEFINE3' => 'USERDEFINE3',
            'request.*.SKU_LIST' => 'SKU_LIST',
            'request.*.SKU_LIST.*.ASNLINENO' => 'SKU_LIST.ASNLINENO',
            'request.*.SKU_LIST.*.SKU' => 'SKU_LIST.SKU',
            'request.*.SKU_LIST.*.ALTERNATE_SKU1' => 'SKU_LIST.ALTERNATE_SKU1',
            'request.*.SKU_LIST.*.SKUDESCRC' => 'SKU_LIST.SKUDESCRC',
            'request.*.SKU_LIST.*.EXPECTEDQTY_EACH' => 'SKU_LIST.EXPECTEDQTY_EACH',
            'request.*.SKU_LIST.*.UOM' => 'SKU_LIST.UOM',
            'request.*.SKU_LIST.*.LINESTATUS' => 'SKU_LIST.LINESTATUS',
            'request.*.SKU_LIST.*.LOTATT05' => 'SKU_LIST.LOTATT05',
            'request.*.SKU_LIST.*.USERDEFINE4' => 'SKU_LIST.USERDEFINE4',
            'request.*.SKU_LIST.*.USERDEFINE5' => 'SKU_LIST.USERDEFINE5',
            'request.*.SKU_LIST.*.USERDEFINE6' => 'SKU_LIST.USERDEFINE6',
        ]);
    }

    /**
     * 入库回传给WMS
     * @param RejectedBill $rejectedBill
     * @return bool
     */
    static public function accomplishToWMS(RejectedBill $rejectedBill)
    {
        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"进入推送WMS入库接口。退单号：".$rejectedBill['logistic_number_return'],Auth::user()['id']);
        ini_set('max_execution_time',2500);
        $bill=$rejectedBill;
        $wmsReceiveds=WMSReflectReceive::where('ASNREFERENCE3',$rejectedBill['logistic_number_return'])
            ->where('is_uploaded',0)->get();
        if($wmsReceiveds->isEmpty()){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"错误，WMS入库接口找不到对应富勒映射表未入库记录。退单号：".$rejectedBill['logistic_number_return'],Auth::user()['id']);
            return false;
        }
        $items=$bill->items()->get();
        $amountsItem=(function()use($items){
            $result=[];
            $items->each(function($item)use(&$result){
                $result[$item['id']]= $item['amount'];
            });
            return $result;
        })();
        $successed=$wmsReceiveds->count();
        $exceptionMessages=[];
        $wmsReceiveds->each(function ($wmsReceived)use(&$bill,&$amountsItem,$items,&$successed){
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"循环WMS映射表(WMS入库接口中)。ASN号：{$wmsReceived['ASNNO']},退单号：".$wmsReceived['ASNREFERENCE3'],Auth::user()['id']);
            if(!$bill && $bill['is_loaded']!=0){
                if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"跳过!!不上传。(WMS入库接口中)。对应循环WMS映射表本地退单记录已入库。退单号：".$bill['logistic_number_return'],Auth::user()['id']);
                return;
            }

            $wmsSkus=$wmsReceived->skus()->get();
            $orderNumberCode=$wmsReceived['ASNREFERENCE1']??$bill['order_number'];
            $amountsSku=(function()use($wmsSkus){
                $result=[];
                $wmsSkus->each(function($sku)use(&$result){
                    $result[$sku['id']]= $sku['EXPECTEDQTY_EACH'];
                });
                return $result;
            })();
            $skuStrList=[];
            $customerCode=$bill->owner()->first()['code'];
            $wmsSkus->each(function(WMSReflectReceiveSku $sku)use(&$items,&$skuList,&$amountsItem,&$amountsSku,&$skuStrList,$wmsReceived,$customerCode){
                $items->each(function(RejectedBillItem $item)use(&$sku,&$amountsItem,&$amountsSku,&$skuStrList,$wmsReceived,$customerCode){
                    if($item['barcode_goods']!=$sku['ALTERNATE_SKU1'])return;
                    if($amountsItem[$item['id']]==0||$amountsSku[$sku['id']]==0)return;
                    $uploadingAmount=(function()use(&$item,&$sku,&$amountsItem,&$amountsSku){
                        if($amountsItem[$item['id']]>$amountsSku[$sku['id']]){
                            $amountsItem[$item['id']]-=$amountsSku[$sku['id']];
                            $amount= $amountsSku[$sku['id']];
                            $amountsSku[$sku['id']]=0;
                            return $amount;
                        }
                        if($amountsItem[$item['id']]<$amountsSku[$sku['id']]){
                            $amount=$amountsItem[$item['id']];
                            $amountsSku[$sku['id']]-=$amount;
                            $amountsItem[$item['id']]=0;
                            return $amount;
                        }
                        $amount=$amountsItem[$item['id']];
                        $amountsItem[$item['id']]=0;
                        $amountsSku[$sku['id']]=0;
                        return $amount;
                    })();
                    if($item['is_loaded']=='已入库'){return;}
                    $STATUS=$item['id_quality_label']==1?'ZP':'CC';
                    $STATUS_code=$item['id_quality_label']==1?'01':'02';
                    $skuStr="
                        {
                            \"ORDERNUMBERCODE\": \"{$wmsReceived['ASNNO']}\",
                            \"ASNLINENO\": \"{$sku['ASNLINENO']}\",
                            \"SKUCODE\": \"{$sku['SKU']}\",
                            \"QUANTITY\": \"{$uploadingAmount}\",
                            \"LOTATT04\": \"{$sku['LOTATT04']}\",
                            \"LOTATT05\": \"{$sku['LOTATT05']}\",
                            \"STATUS\": \"{$STATUS}\",
                            \"PRODUCTION DATE\": \"{$item['made_at']}\",
                            \"EXPIRATION DATE\": \"{$item['validity_at']}\",
                            \"USERDEFINE1\": \"{$customerCode}{$STATUS_code}\",
                            \"USERDEFINE2\": \"\",
                            \"USERDEFINE3\": \"\",
                            \"UNIQUE_CODE_LIST\": [".
                        "]
                        }
                    ";
                    $skuStrList[]=$skuStr;
                });
            });

            if(count($skuStrList)==0){
                if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"错误！没有商品项。(WMS入库接口中)。ASN号：{$wmsReceived['ASNNO']},退单号：{$wmsReceived['ASNREFERENCE3']}",Auth::user()['id']);
                return;
            }
            $skuStrList = implode(',',$skuStrList);
            $json="
                {
                    \"request\": [
                        {
                            \"ORDERNUMBERCODE\": \"{$wmsReceived['ASNNO']}\",
                            \"CUSTOMERID\": \"{$customerCode}\",
                            \"ASNTYPE\": \"{$wmsReceived['ASNTYPE']}\",
                            \"ASNREFERENCE1\": \"{$orderNumberCode}\",
                            \"ADDWHO\": \"WCS\",
                            \"USERDEFINE1\": \"\",
                            \"USERDEFINE2\": \"\",
                            \"USERDEFINE3\": \"\",
                            \"SKU_LIST\": [{$skuStrList}]
                        }
                    ]
                }
                ";
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"完成拼接JSON，准备发送给WMS。(WMS入库接口中)。退单号：{$wmsReceived['ASNREFERENCE3']}，商品项JSON：{$json}",Auth::user()['id']);

            $sendingJson = json_decode($json,true);
            $url=url(config('api.flux.receive.new'));
            try{
                $response = Zttp::post($url, $sendingJson);
            }catch (\Exception $exception){
                Controller::logS(__METHOD__,'Exception_'.__FUNCTION__,'CURL请求异常：'.$exception->getMessage(),null);
                return 'fail';
            }
            $noIssues=true;
            $json = $response->json();
            if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"得到WMS返回。退单号：{$wmsReceived['ASNREFERENCE3']}}，返回：{$response->body()}",Auth::user()['id']);
            if(!$json||!isset($json['Response'])||!$json['Response']['return']['returnFlag']=='1'){
                if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error_'.__FUNCTION__,"WMS入库失败，ASN号：{$wmsReceived['ASNNO']}。退单号：{$wmsReceived['ASNREFERENCE3']}}，返回：{$response->body()}",Auth::user()['id']);
                $noIssues=false;
            }
            if($json&&isset($json['Response'])){
//                if($json['Response']['return']['returnFlag']=='2'){
//                    Controller::logS(__METHOD__,'exception_'.__FUNCTION__,"状态2, WMS返回不正常！按成功跳过。退单号：{$wmsReceived['ASNREFERENCE3']}}",Auth::user()['id']);
//                    return true;
//                }
                if(isset($json['Response']['return']['returnDesc'])&&strpos($json['Response']['return']['returnDesc'],'唯一约束')!==false){
                    $successed-=1;
                    Controller::logS(__METHOD__,'exception_'.__FUNCTION__,"违反唯一约束, WMS返回不正常！按失败计。退单号：{$wmsReceived['ASNREFERENCE3']}}",Auth::user()['id']);
                    return true;
                }
                if(isset($json['Response']['return']['errordescr'])&&strpos($json['Response']['return']['errordescr'],'已完成')!==false){
                    $successed-=1;
                    Controller::logS(__METHOD__,'exception_'.__FUNCTION__,"退单之前已完成, WMS返回不正常！按失败计。退单号：{$wmsReceived['ASNREFERENCE3']}}",Auth::user()['id']);
                    return true;
                }
            }
            if($noIssues&&$json['Response']['return']['returnFlag']=='1'){
                $wmsReceived['is_uploaded']=1;
                $wmsReceived->save();
                Controller::logS(__METHOD__,__FUNCTION__,"成功入库WMS。ASN号：{$wmsReceived['ASNNO']}。退单号：{$wmsReceived['ASNREFERENCE3']}}",Auth::user()['id']);
                return true;
            }else{
                $successed-=1;
                if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,'error'.__FUNCTION__,"入库WMS失败！！ASN号：{$wmsReceived['ASNNO']}。退单号：{$wmsReceived['ASNREFERENCE3']}}",Auth::user()['id']);
            }
        });

        if($successed==$wmsReceiveds->count()){ //bad patch, 正常不需要这两句，作为未知原因的保险
            $rejectedBill = RejectedBill::find($rejectedBill['id']);
            $rejectedBill->is_loaded=1;
            $rejectedBill->save();
        }
        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"入库WMS处理完成，结果为：{$successed}。退单号：{$rejectedBill['logistic_number_return']}}",Auth::user()['id']);
        if($successed==$wmsReceiveds->count())return 'success';
        if(!$successed)return 'fail';
        return 'exception';
    }

}
