<?php

namespace App\Services;

use App\Logistic;
use App\OracleBasCustomer;
use App\Shop;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use App\Traits\ServiceAppAop;


class LogisticService
{
    use ServiceAppAop;
    protected $modelClass=Logistic::class;
    /** @var CacheService $cacheService */
    private $cacheService;
    function __construct(){
        $this->instant($this->cacheService,'CacheService');
    }
    public function getSelection($column = ['id','name'], $type = '快递'){
        return $this->cacheService->getOrExecute('LogisticAll_'.implode("",$column).Str::studly($type),function()use($column,$type){
            $query = Logistic::query()->select($column);
            if ($type)$query->where(function ($query)use($type){
                /** @var Builder $query */
                $query->where("type",$type)->orWhere("type","全部");
            });
            return $query->get();
        },config('cache.expirations.rarelyChange'));
    }

    public function firstOrCreate(array $params, array $values = null){
        return $this->cacheService->getOrExecute('LogisticFirstOrCreate'.md5(json_encode($params).json_encode($values)),function()use($params,$values){
            $logistic = Logistic::query();
            if ($values)return $logistic->firstOrCreate($params, $values);
            return $logistic->firstOrCreate($params);
        },config('cache.expirations.commonFrequent'));
    }

    public function getByWmsOrders($orderHeaders){
        $codes = data_get($orderHeaders,'*.userdefine1');
        $codes = array_unique($codes);
        $codes = array_diff($codes,['','*',null]);
        if(!$codes){return [];}
        $logistics = Logistic::query()->whereIn('code',$codes)->get();

        if($logistics->count() < count($codes)){
            $codes = array_diff($codes,data_get($logistics,'*.code'));
            $logistic_list = $this->createLogisticByCarrierIds($codes);
            $logistics = $logistics->concat($logistic_list);
        }
        return $logistics;
    }

    public function createLogisticByCarrierIds($codes){
        if(!$codes){return [];}
        $baseCustomers = OracleBasCustomer::query()
            ->selectRaw('Customer_Type,CustomerID,Descr_C')
            ->where('Customer_Type','CA')
            ->whereIn('CustomerID',$codes)
            ->get();

        $insert_params = [];
        $created_at = Carbon::now()->format('Y-m-d H:i:s');
        foreach ($baseCustomers as $baseCustomer) {
            $insert_params[] = [
                'code' => $baseCustomer['customerid'],
                'name' => $baseCustomer['descr_c'],
                'created_at' => $created_at
            ];
        }
        try {
            if(count($insert_params) > 0){
                $this->insert($insert_params);
                LogService::log(__METHOD__, __FUNCTION__, '批量创建 Logistic ' . count($insert_params) . json_encode($insert_params) );
            }
        } catch (\Exception $e) {
            LogService::log(__METHOD__, __FUNCTION__, '批量创建 Logistic error' . json_encode($insert_params) . "||".$e->getMessage() . '||' . $e->getTraceAsString() );
        } finally {
            return Logistic::query()->whereIn('code',$codes)->get();
        }
    }


    public function find($id)
    {
        return Logistic::query()->find($id);
    }

    public function getLogisticByCodes($codes)
    {
        $collect = collect();
        if(count($codes) == 0) return $collect;
        foreach ($codes as $code) {
            $collect->push($this->getLogisticByCode($code));
        }
        return $collect;
    }

    public function getLogisticByCode($code){
        return Cache::remember("getLogisticByCode_{$code}", config('cache.expirations.rarelyChange'), function()use($code){
            $logistic = Logistic::query()->where('code',$code)->first();
            if($logistic)return $logistic;
            $baseCustomers = app('OracleBasCustomerService')->first(['Customer_Type'=>'CA','CustomerID'=>$code]);
            if(!$baseCustomers)return null;
            try {
                $logistic = Logistic::query()->create(['name' => $baseCustomers['descr_c'], 'code' => $baseCustomers['customerid']]);
                app('LogService')->log(__METHOD__, __FUNCTION__,'创建Logistic SUCCESS'." || ". json_encode($logistic));
                return $logistic;
            } catch (\Exception $e) {
                app('LogService')->log(__METHOD__, __FUNCTION__,'创建Logistic ERROR'." || ". json_encode($logistic)." || ".json_encode($e->getMessage())." || ".json_encode($e->getTraceAsString()));
                return null;
            }
        });
    }

}
