<?php

namespace App\Http\Controllers;

use App\Logistic;
use App\LogisticNumberFeature;
use App\RejectedBill;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class LogisticNumberFeatureController extends Controller
{
    public function index()
    {
        //
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        //
    }

    public function show(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }

    public function edit(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }

    public function update(Request $request, LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }

    public function destroy(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }
    public function apiComputeLogisticByNumber(Request $request)
    {
        $logisticNumber=$request->input('logistic_number_return');
        if(!$logisticNumber){
            return ['success'=>'false',];
        }
        $logistic=$this->getLogisticByFeatures($logisticNumber);
        if(!$logistic){
            return ['success'=>'false',];
        }
        return ['success'=>'true','logistic'=>$logistic];
    }
    public function getLogisticByFeatures(string $logisticNumber)
    {
        $numberLength=strlen($logisticNumber);
        $char0 = mb_strcut($logisticNumber, 0, 1);
        $logistic_items = DB::table(DB::raw("(select logistic_id,updated_at from logistic_number_features as a where logistic_id in (select logistic_id from
             (select logistic_id from logistic_number_features where name='length' and value='$numberLength') feLen) and
             (name='char0' and value='$char0')) as tableA")
        )->get();
        $targetsIds=$logistic_items->map(function($id){return $id->logistic_id;})->unique()->toArray();
        for ($i=1;$i<LogisticNumberFeature::$featureConsideringLength;$i++){
            if(count($targetsIds)<=1)break;
            $paramName='char'.$i;
            $$paramName = mb_strcut($logisticNumber, 0, 2);
            $logistic_itemsTemp=LogisticNumberFeature::select(['logistic_id','updated_at'])->where('name',$paramName)
                ->where('value',$$paramName)->whereIn('logistic_id',$targetsIds)->get();
            if($logistic_itemsTemp->isNotEmpty()){
                $targetsIds=$logistic_itemsTemp->map(function($id){return $id->logistic_id;})->unique()->toArray();
                $logistic_items=$logistic_itemsTemp;
            }
        }
        if(count($targetsIds)==0)return null;
        $result_logistic_id=$targetsIds[0];
        if(count($targetsIds)>1){
            $finalTarget=$logistic_items->reduce(function ($carry,$item){
               if($carry){
                   if($carry->updated_at > $item->updated_at){
                       return $carry;
                   }
                   return $item;
               }
               return $item;
            });
            $result_logistic_id=$finalTarget->logistic_id;
        }
        return Logistic::find($result_logistic_id);
    }

    public function createFeatures(string $logisticNumber,int $logisticId)
    {
        $logisticNumber = trim($logisticNumber);
        $featureConsideringLength=LogisticNumberFeature::$featureConsideringLength;
        $numberLength=strlen($logisticNumber);
        if($numberLength<$featureConsideringLength)
            $featureConsideringLength=$numberLength;
        if(!$logisticNumber){
            app('LogService')->log(__METHOD__, 'error', '创建退货快递单号特征时，单号传入了空值');
            return null;
        };
        $featuresCreated=[];
        $feature=$this->createFeature($logisticId,'length',$numberLength,100);
        if($feature)$featuresCreated[]=$feature;

        for($i=0;$i<$featureConsideringLength;$i++){
            $chars=mb_strcut($logisticNumber,0,$i+1);
            $feature=$this->createFeature($logisticId,"char$i",$chars,99-$i);
            if($feature)$featuresCreated[]=$feature;
        }
        return $featuresCreated;
    }
    private function createFeature(int $logisticId,string $featureName, string $value,int $weight)
    {
        if(!$value){
            app('LogService')->log(__METHOD__, 'error', "创建退货快递单号特征{$featureName}时，特征值为空");
            return null;
        };
        $feature=LogisticNumberFeature::where('logistic_id',$logisticId)
            ->where('name',$featureName)->where('value',$value)->first();
        if($feature){
            $feature->touch();
        }else{
            $feature=new LogisticNumberFeature(['logistic_id'=>$logisticId,'name'=>$featureName,'value'=>$value,'weight'=>$weight]);
            $feature->save();
            return $feature;
        }
        return null;
    }
    static public function loadRecentRejectedsToFeatures($days,$limit){
        $rejecteds=RejectedBill::where('created_at','>',Carbon::today()->subDays($days))->limit($limit)->get();
        $featureController=new LogisticNumberFeatureController();
        $rejecteds->each(function ($rejected)use($featureController){
            if($rejected['logistic_number_return'])
                $featureController->createFeatures($rejected['logistic_number_return'],$rejected['id_logistic_return']);
        });
    }
}
