<?php

namespace App\Http\Controllers;

use App\Http\Controllers\api\thirdPart\flux\ReceiveController;
use App\Logistic;
use App\OracleActAllocationDetails;
use App\OracleBasSKU;
use App\Owner;
use App\QualityLabel;
use App\RejectedBill;
use App\Services\LogService;
use App\Services\RejectedBillItemService;
use App\Services\RejectedBillService;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator;
use Illuminate\View\View;

class RejectedBillController extends Controller
{
    function __construct()
    {

//        app()->bind('OrderPackageCommoditiesService',OrderPackageCommoditiesService::class);
    }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param Request $request
     * @return Response
     */
    public function store(Request $request)
    {
        //
    }

    public function apiGetRecent()
    {
        if(!Gate::allows('退货管理-查询')){
            return ['success'=>'false','fail_info'=>'没有权限'];}
        $user=Auth::user();
        $rejectedBills = RejectedBill::query()->orderByDesc('id')->whereIn('id_owner',
            $user?app('UserService')->getPermittingOwnerIds($user):[])->limit(20)->get();
        return ['success'=>'true','rejectedBills'=>$rejectedBills->toArray()];
    }

    public function apiStore(Request $request)
    {
        if(!Gate::allows('退货管理-录入')){
            return ['success'=>'false','fail_info'=>'没有权限'];
        }
        $softDeleted=RejectedBill::withTrashed()->where('logistic_number_return',$request->input('logistic_number_return'))->first();
        if($softDeleted&&$softDeleted->trashed()){
            $softDeleted->forceDelete();
        }
        if($request['is_loaded']=='null')$request['is_loaded']=null;
        $errorFields= $this->validator($request->all())->errors()->getMessages();
        if(!empty($errorFields)){
            return ['success'=>'false','error_fields'=>$errorFields,'fail_info'=>'fileds error'];
        }
        $rejectedBill=new RejectedBill($request->all());
        $rejectedBill['id_operator'] = Auth::user()['id'];
        $rejectedBill->save();
        /**
         * @var RejectedBillService $rejectedBillService
         */
        $rejectedBillService=app(RejectedBillService::class);
        $rejectedBillService->joinOrderIssue($rejectedBill);
        $rejectedBillService->updateCheckedStatusByWms($request->input('logistic_number_return'));
//        $rejectedBill->同步问题件退件状态();

        app('LogService')->log(__METHOD__,__FUNCTION__.'_'.$rejectedBill['id'],json_encode($request->toArray()),Auth::user()['id']);
        return ['success'=>'true','id'=>$rejectedBill['id']];
    }

    public function apiUpdate(Request $request)
    {
        if(!Gate::allows('退货管理-编辑')){
            return ['success'=>'false','fail_info'=>'没有权限'];
        }
        if($request['is_loaded']==='null'){
            $request['is_loaded']=null;
        }
        $errorFields= $this->validator($request->all(),true)->errors()->getMessages();
        if(!empty($errorFields)){
            return ['success'=>'false','error_fields'=>$errorFields,'fail_info'=>'fileds error'];
        }
        $rejectedBill=RejectedBill::find($request->input('id'));
        $rejectedBill->fill($request->all());
        $rejectedBill->save();
        /**
         * @var RejectedBillService $rejectedBillService
         */
        $rejectedBillService=app(RejectedBillService::class);
        $rejectedBillService->syncOrderIssue($rejectedBill);
        $rejectedBillService->updateCheckedStatusByWms($rejectedBill->logistic_number_return);
//        $rejectedBill->同步问题件退件状态();

        app('LogService')->log(__METHOD__,__FUNCTION__.'_'.$rejectedBill['id'],json_encode($request->toArray()),Auth::user()['id']);
        return ['success'=>'true'];
    }
    public function apiConfirmBeStored(Request $request)
    {
        if(!Gate::allows('退货管理-编辑')){
            return ['success'=>'false','fail_info'=>'没有权限'];
        }
        $rejectedBill = RejectedBill::find($request->input('id'));

        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,"人工确认入库。退单号：".$rejectedBill['logistic_number_return'],Auth::user()['id']);
        $result_TransferToWMS=ReceiveController::accomplishToWMS($rejectedBill);

        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
        switch ($result_TransferToWMS){
            case 'success':
                $rejectedBill['is_loaded']=1;
                $rejectedBill->update();
                return ['success'=>true];
            case 'fail':
            case 'exception':return ['success'=>false];
        }
    }

    protected function validator(array $data,$isUpdate=false)
    {
        $mobileShouldBeRequired = 'required';
        $logistic=Logistic::find($data['id_logistic_return']);
        if($logistic){if(
            strstr($logistic['name'],'顺丰')
        ){
            $mobileShouldBeRequired = 'nullable';
        }}
        if($data['id_owner']=='4'){
            $mobileShouldBeRequired = 'nullable';
        }
        $mobileDigits = '';
        if($data['mobile_sender']&&$data['mobile_sender'][0]=='1'){
            $mobileDigits = 'digits:11';
        }
        return Validator::make($data, [
            'id_owner' => ['required', 'numeric', 'exists:owners,id'],
            'order_number' => ['nullable', 'string','max:60'],
            'sender' => ['nullable', 'max:50'],
            'mobile_sender' => [$mobileShouldBeRequired, 'max:20',$mobileDigits],
            'logistic_number' => ['nullable', 'max:60'],
            'logistic_number_return' => ['required','string', 'max:60'],
            'id_logistic_return' => ['required', 'numeric', 'exists:logistics,id'],
            'fee_collected' => ['nullable','between:0,99999','numeric'],
            'is_loaded' => ['nullable'],
        ],[
            'mobile_sender.digits'=>'如果是手机则必须为11位',
        ],[
            'id_owner'=>'客户名称',
            'order_number'=>'订单号',
            'sender'=>'寄件人',
            'mobile_sender'=>'寄件人手机',
            'logistic_number'=>'原单号',
            'logistic_number_return'=>'退回单号',
            'id_logistic_return'=>'物流公司',
            'fee_collected'=>'到付费用',
            'is_loaded'=>'是否入库',
        ]);
    }

    public function apiSetIsLoadedAll(Request $request)
    {
        if(!Gate::allows('退货管理-编辑')){ return redirect(url('/'));  }
        $ids=$request->input('ids')??'';
        $rejecteds=RejectedBill::with('items')->whereIn('id',$ids)->get();
        $is_loaded = $request->input('is_loaded');
        switch ($is_loaded){
            case '0':$is_loaded=0;break;
            case '1':$is_loaded=1;break;
            case '2':$is_loaded=2;break;
            case '3':$is_loaded=3;break;
            case 'null':$is_loaded=null;break;
        }
        $rejecteds->each(function($rejected)use($is_loaded,$request){
            $rejected['is_loaded']=$is_loaded;
            $re=$rejected->update();
            if (!$re){
                return ['success'=>'false','fail_info'=>"数据 {$rejected['id']} 更新失败"];
            }
            $is_loadedItem='未入库';
            switch ($request->input('is_loaded')){
                case '1':$is_loadedItem='已入库';break;
                case '2':$is_loadedItem='待推单';break;
                case '0':$is_loadedItem='未入库';break;
                case '3':$is_loadedItem='未入库';break;
                case 'null':$is_loadedItem='无需入库';break;
            }
            $rejected->items()->each(function($item)use($is_loadedItem){
                $item['is_loaded']=$is_loadedItem;
                $item->save();
            });
        });
        return ['success'=>'true'];
    }

    /**
     * Display the specified resource.
     *
     * @param RejectedBill $rejectedBill
     * @return Response
     */
    public function show(RejectedBill $rejectedBill)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param RejectedBill $rejectedBill
     * @param Request $request
     * @return Factory|RedirectResponse|Response|Redirector|View
     */
    public function edit(RejectedBill $rejectedBill,Request $request)
    {
        if(!Gate::allows('退货管理-编辑')){ return redirect(url('/'));  }
        $user=Auth::user();
        $owners=Owner::all()->whereIn('id',
            $user?app('UserService')->getPermittingOwnerIds($user):[])->sortBy('name');
        $logistics=Logistic::all()->sortBy('name');
        $qualityLabels=QualityLabel::all()->sortBy('name');
        $rejectedBill['is_loaded'] = $rejectedBill['is_loaded_null'];
        $rejectedBill['isEditing'] = false;
        $rejectedBill['is_at_edit_page'] = true;
        return view('rejected.edit',compact('owners','logistics','qualityLabels','rejectedBill'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param RejectedBill $rejectedBill
     * @return Response
     */
    public function update(Request $request, RejectedBill $rejectedBill)
    {
        //
    }

    public function destroy(RejectedBill $rejectedBill)
    {
        if(!Gate::allows('退货管理-删除')){ return redirect(url('/'));}
        $re=$rejectedBill->delete();
        app('LogService')->log(__METHOD__,__FUNCTION__,$rejectedBill->toJson(),Auth::user()['id']);
        return ['success'=>$re];
    }

    public function apiLogisticNumberReturnIsUnique(Request $request)
    {
        if(!Gate::allows('退货管理-查询')){ return redirect(url('/'));}
        $logistic_number_return = $request->input('logistic_number_return');
        $bill=RejectedBill::select('logistic_number_return')->where('logistic_number_return',$logistic_number_return)->first();
        if(!$bill)return ['success'=>'true','result'=>'false'];
        return ['success'=>'true','result'=>'true'];
    }

    function seekOrder(Request $request)
    {
        if (!$request['logistic_number_return'])return ['success'=>false];
        /** @var RejectedBillService $service */
        $service = app('RejectedBillService');
        $result = $service->findOrderByOrderPackage($request['logistic_number_return']);
        if($result)return ['success' => true,'data' => $result];
        $result = $service->findOrderByStoreRejected($request['logistic_number_return']);
        if($result)return ['success' => true,'data' => $result];
        $result = $service->findOrderByOrderHeader($request['logistic_number_return']);
        if($result)return ['success' => true,'data' => $result];
        $result = $service->findOrderByOrderIssue($request['logistic_number_return']);
        if($result)return ['success' => true,'data' => $result];
        else return ['success'=>false];
    }

    public function disposeImportApi(Request $request)
    {
        if(!Gate::allows('退货管理-编辑'))
            return ['success'=>false,'message'=>'没有对应权限'];
        /**
         * @var RejectedBillItemService $rejectedBillItemService
         * @var RejectedBillService $service
         */
        $service = app('RejectedBillService');
        $rejectedBillItemService = app('RejectedBillItemService');
        $params = [['logistic_number_return','order_number','fee_collected']];
        $logistic_numbers = [];             // 原单单号
        $logistic_number_map = [];
        $logistic_number_return = [];       // 退回单号
        $logistic_number_return_map = [];

        $errors = [];
        $array = explode("\n",$request['dataText']); //拆分行
        foreach ($array as  $i=>$item) {
            $items = [];
            preg_match('/^(\w*?)[\s,，；;](\w*?)[\s,，；;](\d.*)$/u',$item,$items);
            if(count($items) < 1)
                preg_match('/^(\w*?)[\s,，；;](\w*?)$/u',$item,$items);
            $head = '第'.($i+1).'行';
            if(count($items) < 3){
                $errors[$head] = ['数据不完整'];
                unset($items);
                continue;
            }
            array_shift($items);
            isset($items[1]) ? $logistic_numbers[] = $items[1] : null;
            isset($items[0]) ? $logistic_number_return[] = $items[0] : null;
            $param = [$items[0] ?? null, $items[1] ?? null, $items[2] ?? null];
            $params[] = $param;
            $logistic_number_map[$items[1]] = $param;
            $logistic_number_return_map[$items[0]] =$param;
            unset($param);
        }
        $rejectedBill_collect = collect();

        // 对已用的进行修改
        $update_fee_params = [['id','order_number','fee_collected']];                //对原有的进行修改 有到付费用
        $update_params = [['id','order_number']];                                    // 无到付费用
        $exist_picktotraceid = [];                                                      // 已有退回单号
        $rejectedBills = RejectedBill::query()->whereIn('logistic_number_return',$logistic_number_return)->get();
        $rejectedBills->each(function($rejectedBill)use(&$update_fee_params,&$update_params,$logistic_number_return_map,&$exist_picktotraceid,&$rejectedBill_collect){
            $rejectedBill_collect->push($rejectedBill);
            $logistic_number_return =  $rejectedBill->logistic_number_return; //退回单号
            $params = $logistic_number_return_map[$logistic_number_return];
            $rejectedBill->logistic_number ? $exist_picktotraceid[$rejectedBill->logistic_number] = $rejectedBill->logistic_number : null;    // 记录已有原单单号
            if(isset($params[2])){
                $update_fee_params[] = ['id'=>$rejectedBill->id,'order_number'=>$params[1],'fee_collected'=>$params[2]];
            }else if(isset($params[1])){
                $update_params[] = ['id'=>$rejectedBill->id,'order_number'=>$params[1]];
            }
        });
        // 对不存在的进行创建
        $inner_items_params = [];
        $details = OracleActAllocationDetails::query()->with('oracleDocOrderHeader.oracleBASCustomer')->whereIn('picktotraceid',$logistic_numbers)->get();
        $bas_sku_map =[];
        OracleBasSKU::query()->selectRaw('SKU,CustomerID,Alternate_SKU1,Descr_C')->whereIn('SKU',array_diff(data_get($details,'*.sku'),[' ','*']))->whereIn('CustomerID',data_get($details,'*.customerid'))->get()
            ->each(function($bas_sku)use(&$bas_sku_map){
                $key = 'Sku = '.$bas_sku->sku.' CustomerID = '.$bas_sku->customerid;
                $bas_sku_map[$key] = $bas_sku;
            });
        $details = $details->groupBy('picktotraceid');

        $details->each(function($items,$key)use(&$inner_params,$bas_sku_map,$exist_picktotraceid,&$inner_items_params,&$rejectedBill_collect,$logistic_number_map){
            if(!isset($exist_picktotraceid[$key])){
                $order_header = $items->first()->oracleDocOrderHeader;
                $owner = app('OwnerService')->firstOrCreate(['name' => $order_header->oracleBASCustomer->descr_c],
                    ['name' => $order_header->oracleBASCustomer->descr_c, 'code' => $order_header->oracleBASCustomer->descr_c]);
                $logistic = app('LogisticService')->firstOrCreate(['name' => $order_header->carriername],
                    ['name' => $order_header->carriername, 'code' => $order_header->carriername]);
                $rejectedBill = RejectedBill::query()->create([
                    'id_owner' => $owner->id ?? '',
                    'sender' => $order_header->c_contact,
                    'logistic_number_return' => $logistic_number_map[$key][0] ?? '',
                    'id_logistic_return' =>$logistic->id ?? '',
                    'fee_collected' => $logistic_number_map[$key][2] ?? '',
//                    'order_number' =>$order_header->soreference1,
                    'mobile_sender' => empty($order_header->c_tel2)?$order_header->c_tel1:$order_header->c_tel2,
                    'order_number' => $logistic_number_map[$key][1] ?? '',
                    'remark' => $order_header->notes,
                    'is_loaded' =>0,
                    "id_operator" => Auth::id(),
                ]);
                $rejectedBill_collect->push($rejectedBill);
                LogService::log(__METHOD__,"生成退货单",json_encode($rejectedBill),Auth::user()['id']);
                // 获取创建items
                $items->each(function($item)use($rejectedBill,$bas_sku_map,&$inner_items_params){
                    $key = 'Sku = '.$item->sku.' CustomerID = '.$item->customerid;
                    $bas_sku = $bas_sku_map[$key] ?? '';
                    $date = date('Y-m-d H:i:s');
                    $inner_items_params[] = [
                        'id_rejected_bill' => $rejectedBill->id ?? '',
                        'barcode_goods' => $bas_sku['alternate_sku1'] ?? '',
                        'name_goods' => $bas_sku['descr_c'],
                        'amount' => $item->qty_each,
                        'id_quality_label' => 1,
                        'created_at' => $date,
                        'updated_at' => $date
                    ];
                });
            }
        });
        try {
            if (count($update_fee_params) > 1) {
                $service->batchUpdate($update_fee_params);
            }
            if (count($update_params) > 1) {
                $service->batchUpdate($update_params);
            }
            if(count($inner_items_params) > 0){
                $rejectedBillItemService->insert($inner_items_params);
                LogService::log(__METHOD__, "批量生成退货单详情", json_encode($inner_items_params), Auth::user()['id']);
            }
            $rejectedBill_collect->each(function ($rejectedBill)use($service){
                $service->joinOrderIssue($rejectedBill);
                $service->syncOrderIssue($rejectedBill);
            });
            return ['success'=>true];
        } catch (\Exception $e) {
            LogService::log(__METHOD__, __FUNCTION__.' error', '修改退回单号 失败', json_encode($request->getContent()).' ||'.json_encode($e->getMessage())." || ".json_encode($e->getTraceAsString()));
            return ['success'=>false,'error'=>['导入处理发生异常'=>$e->getMessage()]];
        }
    }

    public function importRejectedNumber(Request $request)
    {
        if(!Gate::allows('退货管理-编辑'))
            return redirect(url('/'));
        return view('rejected.importRejectedNumber');
    }

}
