<?php

namespace App\Http\Controllers\Admin;

use App\Events\OperationLoggedEvent;
use App\Events\OrderCommissionSetedEvent;
use App\Exports\PartnerWithdrawExport;
use App\Http\Controllers\Controller;
use App\Http\Response\ResponseJson;
use App\Jobs\AddErrorLog;
use App\Models\Coach;
use App\Models\CustomerServiceUser;
use App\Models\MainCoach;
use App\Models\Order;
use App\Models\OrderCommission;
use App\Models\Partner;
use App\Models\PartnerWithdrawal;
use App\Models\ServiceUser;
use App\Validators\CommissionValidator;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;

class OrderCommissionController extends Controller
{
    use ResponseJson;
    private Order $order;
    private CommissionValidator $validator;
    public function __construct(Order $order, CommissionValidator $commissionValidator)
    {
        $this->order = $order;
        $this->validator = $commissionValidator;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $order = $this->order->findOrFail($request->get('order_id'));
        $list = OrderCommission::with('service_user:id,name,mobile,user_id','user:id,avatar')
            ->where('order_id', $order->id)
            ->get();
        return $this->success('ok', $list);
    }

    public function getList(Request $request)
    {
        try {
            $role = $request->get('role');
            $id = $request->get('id');
            $page_size = $request->get('page_size',15);

            $serviceUser = match ($role) {
                "1" => new MainCoach(),
                "2" => new Coach(),
                "3" => new CustomerServiceUser(),
                "4" => new Partner(),
                "5" => new ServiceUser(),
                default => throw new Exception('操作类型错误'),
            };
            $serviceUser = $serviceUser->findOrFail($id);

            $partner = $serviceUser->{$role !="4" ? 'partner' : ''} ?? $serviceUser;

            $list = OrderCommission::with(['offline_order:id,order_id,name,mobile','main_order:id,trade_no'])->where('user_id',$partner->user_id)
                ->orderByDesc('id')
                ->paginate(perPage: $page_size);

            //数据格式处理
            $list->each(function ($order_commission){
                $order_commission->name = $order_commission->offline_order->name;
                $order_commission->mobile = $order_commission->offline_order->mobile;
                $order_commission->trade_no = $order_commission->main_order->trade_no;
                unset($order_commission->offline_order);
                unset($order_commission->main_order);
            });

            return $this->success('ok',$list);

        }catch (ModelNotFoundException){
            return $this->jsonResponse(1,'用户信息不存在');
        }catch (Exception $e){
            return $this->jsonResponse(1,$e->getMessage());
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(Request $request)
    {
        try {
            //数据验证
            $data = $request->only(['order_id','role','user_id','commission_type','commission_val','send_event','delay']);
            $this->validator->scene('create')->validate($data);
            //获取对应订单
            $order = $this->order->findOrFail($data['order_id']);
            if ($order->status !='NOTSTART'){
                throw new Exception('此订单已开始服务,不可创建分佣方案');
            }

            //计算佣金
            $data = $this->getCommissionData($data,$order);

            $commission = OrderCommission::create($data);

            //发送通知
            OrderCommissionSetedEvent::dispatch($commission);

            //操作记录
            OperationLoggedEvent::dispatch("给订单: $order->id 创建了新的分佣方案:$commission->id");

            return $this->success('ok',$commission);
        }catch (ModelNotFoundException){
            return $this->jsonResponse(1,'订单不存在');
        } catch (Exception|ValidationException $e) {
            return $this->jsonResponse(1,$e->getMessage());
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {

    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        try {
            //数据验证
            $data = $request->only(['role', 'user_id', 'commission_type', 'commission_val','send_event','delay']);
            $this->validator->scene('update')->validate($data);

            //获取分佣详情
            $commission = OrderCommission::with('main_order')->findOrFail($id);
            if ($commission->status !=0){
                throw new Exception('此分佣已入账,不可更改');
            }

            //计算佣金
            $data = $this->getCommissionData($data,$commission->main_order,$id);

            //更新分佣
            $commission->update($data);

            //操作记录
            OperationLoggedEvent::dispatch("更新了订单: $commission->main_order->id 的分佣方案:$commission->id");

            return $this->success('ok');

        } catch (ModelNotFoundException){
            return $this->jsonResponse(1,'未找到此分佣记录');

        }catch (Exception|ValidationException $e) {
            return $this->jsonResponse(1,$e->getMessage());

        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public function destroy($id)
    {
        try {
            //获取分佣详情
            $commission = OrderCommission::findOrFail($id);
            if ($commission->status !=0)throw new Exception('此分佣已入账,不可更改');
            $commission->delete();

            //操作记录
            OperationLoggedEvent::dispatch("删除了订单: {$commission->main_order->id} 的分佣方案:$id");

            return $this->success('ok');
        }catch (ModelNotFoundException){
            return $this->jsonResponse(1,'未找到此分佣记录');
        }catch (Exception $e){
            return $this->jsonResponse(1,$e->getMessage());
        }

    }

    private function getCommissionData($data,$order,$id = null)
    {

        // 计算佣金
        if ($data['commission_type'] == 1) {
            // 比例分佣
            $commission_percentage = bcdiv($data['commission_val'], 100,4);
            $data['commission_amount'] = bcmul($order->price, $commission_percentage,2);
        } else {
            // 固定金额
            $data['commission_amount'] = bcmul($data['commission_val'],1,2);
        }

        //获取当前订单已设置的分佣方案总金额
        $commissions_total_amount = $order->commission()
            ->when($id,function ($query) use ($id) {
                $query->where('id','!=',$id);
            })
            ->sum('commission_amount');

        //验证订单剩余金额是否足够本次分佣方案
        $residue_amount = bcsub($order->price,$commissions_total_amount,2);
        if ($data['commission_amount'] >$residue_amount){
            throw new Exception('订单剩余金额不足以本次分佣方案');
        }
        //根据角色获取延迟
//        $data['send_event'] = 'order_started';
//        $delay_arr = [0,7,3,3,3];//1推荐人7天，2教练3天，3副教练3天，4客服3天
//        $delay = $delay_arr[$data['role']];
//        $data['delay'] = $delay;

        return $data;
    }

    public function getPartnerWithdraw(Request $request){
        try {
            $user_id = $request->get('user_id');
            $bill = $request->get('bill');
            $is_export = $request->get('is_export');
            $query = PartnerWithdrawal::query();

            if($bill == 1){
                $query->whereNotNull('bill_pic');
            }elseif($bill == 2){
                $query->whereNull('bill_pic');
            }

            $query->where('user_id',$user_id);

            if($is_export){
                $list = $query->get();
                return Excel::download(new PartnerWithdrawExport($list), '订单统计.xlsx');
            }

            $list = $query->paginate();

            return $this->success('ok',$list);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getPartnerWithdraw file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }
}
