<?php

namespace App\Listeners;

use App\Events\WaybillPriceModelEvent;
use App\Region;
use App\Waybill;
use App\WaybillFinancialSnapshot;
use App\WaybillPayoff;
use App\WaybillFinancialExcepted;
use App\WaybillPriceModel;
use Illuminate\Database\Eloquent\Builder;

class WaybillPriceModelListener
{
    public function waybillPriceModel_check_waybill(WaybillPriceModel $waybillPriceModel){

        $waybills=Waybill::query()->with(["logistic"])->where('type','专线')
            ->where('status','!=','已完结');

        //条件携带承运商
        /** @var \stdClass $waybillPriceModel */
        $logisticId = $waybillPriceModel->logistic_id;
        $waybills->where('logistic_id',$logisticId);
        //市不存在
        if(!$waybillPriceModel->city_id){
            $cities=Region::query()->select('id')->where('parent_id',$waybillPriceModel['province_id'])->get();
            $province = Region::query()->find($waybillPriceModel['province_id']);
            $cityIds=$cities->map(function ($city){
                return $city['id'];
            });
            //条件携带省
            $waybills->where(function ($query)use($cityIds,$province){
                    $province = $province->name ?? "";
                    /** @var Builder $query */
                    $query->whereIn('destination_city_id',$cityIds)->orWhereHas("order",function ($query)use($province){
                        /** @var Builder $query */
                        $query->where("province","like",$province."%");
                    });
                });
            //市不存在，价格区间不存在
            if (!$waybillPriceModel->range_max){
                $waybills->where('carrier_weight_unit_id',$waybillPriceModel->unit_id)
                    ->orWhere('carrier_weight_unit_id_other',$waybillPriceModel->unit_id);
            }else{
                //市不存在，价格区间存在
                $waybills->whereRaw('carrier_weight <= ? AND carrier_weight > ? AND carrier_weight_unit_id = ?',[$waybillPriceModel->range_max,$waybillPriceModel->range_min,$waybillPriceModel->unit_id])
                    ->orWhereRaw('carrier_weight_other <= ? AND carrier_weight_other > ? AND carrier_weight_unit_id_other = ?',[$waybillPriceModel->range_max,$waybillPriceModel->range_min,$waybillPriceModel->unit_id]);
            }
        }else{
            //市存在
            //携带城市条件
            $city = Region::query()->find($waybillPriceModel->city_id);
            $id = $city->id ?? "";
            $name = $city->name ?? "";
            $waybills->where(function ($query)use($id,$name){
                /** @var Builder $query */
                $query->where("destination_city_id",$id)->orWhereHas("order",function($query)use($name){
                    /** @var Builder $query */
                    $query->where("city",'like',$name."%");
                });
            });
            if ($waybillPriceModel->range_max){
                //价格区间存在
                $waybills->whereRaw('carrier_weight <= ? AND carrier_weight > ? AND carrier_weight_unit_id = ?',[$waybillPriceModel->range_max,$waybillPriceModel->range_min,$waybillPriceModel->unit_id])
                    ->orWhereRaw('carrier_weight_other <= ? AND carrier_weight_other > ? AND carrier_weight_unit_id_other = ?',[$waybillPriceModel->range_max,$waybillPriceModel->range_min,$waybillPriceModel->unit_id]);
            }else{
                //价格区间不存在
                $waybills->where('carrier_weight_unit_id',$waybillPriceModel->unit_id)
                    ->orWhere('carrier_weight_unit_id_other',$waybillPriceModel->unit_id);
            }
        }
        return $waybills->get();
    }

    /**
     * Handle the event.
     *
     * @param  WaybillPriceModelEvent  $event
     *
     * @return void
     *
     * @throws
     */
    public function handle(WaybillPriceModelEvent $event)
    {
        $waybillPriceModel=$event->waybillPriceModel;
        $waybills=$this->waybillPriceModel_check_waybill($waybillPriceModel);
        /** @var \stdClass $waybillPriceModel */
        if ($waybills){
            foreach ($waybills as $waybill){
                //修改运单表运费
                /** @var \stdClass $carrier */
                $carrier=$waybill->logistic;
                if ($waybill->carrier_weight<$waybillPriceModel->initial_weight){
                    $fee=(($waybillPriceModel->unit_price)*($waybillPriceModel->initial_weight))+$carrier->delivery_fee;
                }else{
                    $fee=(($waybillPriceModel->unit_price)*$waybill->carrier_weight)+$carrier->delivery_fee;
                }
                $waybill->fee=$fee;
                $waybill->save();
                $total_receivable=($waybill->charge);
                $total_expense=($waybill->pick_up_fee)+($waybill->other_fee)+($waybill->fee);

                //修改财务表信息
                if ($total_receivable){
                    $waybillPayoff=WaybillPayoff::query()->where('waybill_id','=',$waybill->id)->first();
                    if ($waybillPayoff){
                        $waybillPayoff->total_expense=$total_expense;
                        $waybillPayoff->total_receivable=$total_receivable;
                        $waybillPayoff->gross_margin=$total_receivable-$total_expense;
                        $waybillPayoff->gross_profit_rate=(($total_receivable-$total_expense)/$total_receivable);
                        $waybillPayoff->save();
                    }else{
                        WaybillPayoff::query()->create([
                            'waybill_id'=>$waybill->id,
                            'total_expense'=>$total_expense,
                            'total_receivable'=>$total_receivable,
                            'gross_margin'=>$total_receivable-$total_expense,
                            'gross_profit_rate'=>(($total_receivable-$total_expense)/$total_receivable),
                        ]);
                    };
                    $waybillFinancialExcepted=WaybillFinancialExcepted::query()->where('waybill_id',$waybill->id)->first();
                    if ($waybillFinancialExcepted){
                        $waybillFinancialExcepted->delete();
                        $waybill->status='完结';
                        $waybillPayoff=WaybillPayoff::query()->where('waybill_id','=',$waybillFinancialExcepted->waybill_id)->first();
                        $waybillPayoff->load(["waybill"]);
                        $waybillPayoff->waybill->load(["owner","carrier","origination_city","destination_city","warehouse_weight_unit","carrier_weight_unit","carType","waybillAuditLogs"]);
                        $waybillPayoff->waybill->waybillAuditLogs->load(["user"]);
                        $waybillPayoffJson=json_encode($waybillPayoff,JSON_UNESCAPED_UNICODE);
                        WaybillFinancialSnapshot::query()->create([
                            'waybill_id'=>$waybillFinancialExcepted->waybill_id,
                            'json_content'=>$waybillPayoffJson,
                        ]);
                    }
                }
                if ($waybill->waybill_price_model_id!=$waybillPriceModel->id){
                    $waybill->waybill_price_model_id=$waybillPriceModel->id;
                }
                $waybill->save();
            }
        }
    }
}
