<?php

namespace App\Services;

use App\Services\common\BatchUpdateService;
use App\Services\common\DataHandlerService;
use App\Services\common\QueryService;
use App\Store;
use Carbon\Carbon;


Class StoreService
{
    private function conditionQuery(array $params){
        $stores=Store::query()->with(['storeItems.store','warehouse','owner'])->whereNotIn('stored_method',['快速入库','正常'])->orderBy('id','DESC');
        $columnQueryRules=[
            'asn_code' => ['like' => ''],
            'created_at_start' => ['alias' => 'created_at' , 'startDate' => ' 00:00:00'],
            'created_at_end' => ['alias' => 'created_at' , 'endDate' => ' 23:59:59'],
            'owner_id' => ['multi' => ','],
            'warehouse_id' => ['multi' => ','],
            'status' => ['multi' => ','],
            'stored_method' => ['multi' => ','],
            'id' => ['multi' => ',']
        ];
        $stores = app(QueryService::class)->query($params,$stores,$columnQueryRules,'stores');
        return $stores;
    }
    public function paginate(array $params){
        return $this->conditionQuery($params)->paginate($params['paginate'] ?? 50);
    }

    public function create(array $params)
    {
        return Store::query()->create($params);
    }

    public function syncWmsAsnData($startDate)
    {
        $this->storeCreateByWms($startDate);
        $this->storeUpdateByWms($startDate);
    }

    public function storeCreateByWms($startDate)
    {
        /** @var OracleDocAsnHerderService $oracleDocAsnHerderService */
        $oracleDocAsnHerderService = app(OracleDocAsnHerderService::class);
        $asnHerders = $oracleDocAsnHerderService->getWmsAsnOnStartDateCreate($startDate);
        $this->createStore($asnHerders);
    }

    public function storeUpdateByWms($startDate)
    {
        /** @var OracleDocAsnHerderService $oracleDocAsnHerderService */
        $oracleDocAsnHerderService = app(OracleDocAsnHerderService::class);
        $asnHerders = $oracleDocAsnHerderService->getWmsAsnOnStartDateEdit($startDate);
        $this->updateStore($asnHerders);
    }

    public function createStore($asnHerders)
    {
        if ($asnHerders->isEmpty())return null;
        /**
         * @var OwnerService $ownerService
         * @var WarehouseService $wareHouseService
         */
        $ownerService = app(OwnerService::class);
        $owners=$ownerService->getByWmsOrders($asnHerders);
        $wareHouseService=app(WarehouseService::class);
        $warehouses=$wareHouseService->getByWms($asnHerders);
        foreach ($owners as $owner) {
            $owners_code_map[$owner->code] = $owner;
        }
        foreach ($warehouses as $warehouse) {
            $warehouses_code_map[$warehouse->code] = $warehouse;
        }

        $params=$this->getParamsByAsnHeader($asnHerders,$owners_code_map,$warehouses_code_map);
        if(count($params)> 0){
            $this->insertStore($params);
        }
        /** @var StoreItemService $storeItemService */
        $storeItemService = app(StoreItemService::class);
        $storeItemService->storeItemCreateByWms($asnHerders);
        /** @var RejectedBillService $rejectedBillService */
        $rejectedBillService=app(RejectedBillService::class);
        $rejectedBillService->syncLoadedStatusByAsnHerder($asnHerders);
        unset($asnHerders,$owners_code_map,$warehouses_code_map);
    }
    public function getParamsByAsnHeader($asnHerders,$owners_code_map,$warehouses_code_map)
    {
        $params = [];
        $stores = Store::query()->whereIn('asn_code',data_get($asnHerders,'*.asnno'))->get();
        $store_asn_code_map = [];
        foreach ($stores as $store) {
            $store_asn_code_map[$store->asn_code]= $store;
        }
        foreach ($asnHerders as $asnHerder) {
            if($store_asn_code_map[$asnHerder->asnno] ?? false)continue;
            $owner = $owners_code_map[$asnHerder->customerid] ?? null;
            $warehouse=$warehouses_code_map[$asnHerder->warehouseid] ?? null;
            $params[] = [
                'asn_code' => $asnHerder->asnno,
                'warehouse_id' =>$warehouse->id??null,
                'owner_id' => $owner->id??null,
                'stored_method' =>$asnHerder->asnType?$asnHerder->asnType->codename_c:'',
                'status' =>$asnHerder->asnStatus?$asnHerder->asnStatus->codename_c:'',
                'remark' => $asnHerder->notes??null,
                'created_at'=>$asnHerder->addtime??null,
                'updated_at'=>$asnHerder->edittime??null,
            ];
        }
        return $params;
    }
    public function insertStore(array $params){
        if(count($params) === 0) return [];
        try {
            $this->insert($params);
            LogService::log(__METHOD__,__FUNCTION__,'批量创建 store success'.count($params).json_encode($params));
        } catch (\Exception $e) {
            LogService::log(__METHOD__,__FUNCTION__,'批量创建 store error'.json_encode($params).'||'.$e->getMessage().'||'.$e->getTraceAsString());
        }
    }

    public function updateStore($asnHerders)
    {
        if(!$asnHerders || $asnHerders->count() == 0){return null;}
        /** @var DataHandlerService $dataHandlerService */
        $dataHandlerService =  app(DataHandlerService::class);
        $stores = $this->getByWms($asnHerders);
        $store_asn_code_map =  $dataHandlerService->dataHeader(['asn_code'],$stores);
        $owners = app(OwnerService::class)->getByWmsOrders($asnHerders);
        $owner_code_map = $dataHandlerService->dataHeader(['code'],$owners);
        $warehouses = app(WarehouseService::class)->getByWms($asnHerders);
        $warehouses_map = $dataHandlerService->dataHeader(['code'],$warehouses);
        $updateParams = [[
            'id','asn_code','warehouse_id','owner_id','stored_method','status','remark','updated_at'
        ]];
        foreach ($asnHerders as $asnHerder) {
            $store =$dataHandlerService->getKeyValue(['asn_code'=>$asnHerder->asnno],$store_asn_code_map);
            if(!$store){continue;}
            $owner = $dataHandlerService->getKeyValue(['code'=>$asnHerder->customerid] ,$owner_code_map);
            $warehouse=$dataHandlerService->getKeyValue(['code'=>$asnHerder->warehouseid],$warehouses_map);
            $owner_id = $owner->id ?? null;
            $warehouse_id=$warehouse->id??null;

            if( $store->asn_code != $asnHerder->asnno ||
                $store->warehouse_id!=$warehouse_id ||
                $store->owner_id != $owner_id ||
                $store->stored_method != $asnHerder->asnType->codename_c||
                $store->status !=$asnHerder->asnStatus->codename_c||
                $store->remark != $asnHerder->notes){
                $updateParams[] = [
                    'id'=>$store->id,
                    'asn_code'=>$asnHerder->asnno,
                    'warehouse_id'=>$warehouse_id,
                    'owner_id' => $owner_id,
                    'stored_method' =>$asnHerder->asnType?$asnHerder->asnType->codename_c:'',
                    'status' =>$asnHerder->asnStatus?$asnHerder->asnStatus->codename_c:'',
                    'remark' => $asnHerder->notes,
                    'updated_at' =>$asnHerder->edittime,
                    ];
            }
        }
        if(count($updateParams) > 1) $this->batchUpdate($updateParams);
        $this->createStore($asnHerders);
        /** @var StoreItemService $storeItemService */
        $storeItemService = app(StoreItemService::class);
        $storeItemService->storeItemUpdateByWms($asnHerders);
        /** @var RejectedBillService $rejectedBillService */
        $rejectedBillService=app(RejectedBillService::class);
        $rejectedBillService->syncLoadedStatusByAsnHerder($asnHerders);
        unset($updateParams,$asnHerders);
    }
    public function insert($params){
        return Store::query()->insert($params);
    }
    public function batchUpdate($params){
        return app(BatchUpdateService::class)->batchUpdate('stores',$params);
    }
    public function getByWms($asnHerders){
        if(!$asnHerders){return null;}
        $asn_nos = array_unique(data_get($asnHerders,'*.asnno'));
        return Store::query()->whereIn('asn_code',$asn_nos)->get();
    }
}
