<?php

namespace App\Http\Controllers\H5;

use App\Events\WithdrawalsApplyEvent;
use App\Http\Controllers\Controller;
use App\Http\Response\ResponseJson;
use App\Jobs\AddErrorLog;
use App\Models\Partner;
use App\Models\PartnerAccount;
use App\Models\PartnerCommission;
use App\Models\PartnerWallet;
use App\Models\PartnerWithdrawal;
use App\Validators\WithdrawalsValidator;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PartnerWithdrawalsController extends Controller
{
    //
    use ResponseJson;


    private WithdrawalsValidator $validator;
    private Partner $partner;
    private $user;

    public function __construct(Partner $partner, WithdrawalsValidator $validator)
    {
        $this->partner = $partner;
        $this->validator = $validator;
        $user = auth('api')->user();
        if (!$user)return $this->jsonResponse(2,'未登录');
        $this->user = $user;
    }

    public function apply(Request $request)
    {
        try {
            $user_id = $this->user->id;

            // 数据验证
            $this->validator->scene('apply')->validate($request->all());

            // 获取要申请的佣金记录详情
            $commissionIds = $request->input('commission_ids');
            $commissions = PartnerCommission::whereIn('id',$commissionIds)
                ->whereIn('status',[1,3,4])
                ->select(['id','amount'])
                ->where('user_id', $user_id)
                ->get();
            if (count($commissionIds) !== count($commissions)) {
                throw new \Exception('所选记录状态不正确,请确认后再次申请');
            }


            DB::beginTransaction();

            $total_amount = $commissions->sum('amount');
            // 更新用户钱包余额和提现中金额
            $wallet = PartnerWallet::where('user_id', $user_id)->firstOrFail();
            if ($wallet->balance < $total_amount){
                throw new \Exception('可提现余额不足');
            }
            $wallet->update([
                'balance' => DB::raw("balance - $total_amount"),
                'withdrawn_amount' => DB::raw("withdrawn_amount + $total_amount"),
            ]);

            // 创建提现申请
            $withdraw = PartnerWithdrawal::create([
                'user_id' => $user_id,
                'amount' => $total_amount,
                'bill_pic' => $request->input('bill_pic'),
                'info' => [
                    'bank_of_deposit' => $request->input('bank_of_deposit'),
                    'bank_name' => $request->input('withdrawals_name'),
                    'bank_num' => $request->input('withdrawals_num'),
                    'type' => $request->input('withdrawals_type'),
                ],
                'remark' => $request->input('remark'),
                'status' => 0 // 提现状态为待审核
            ]);

            // 变更佣金申请状态
            PartnerCommission::whereIn('id',$commissionIds)->update([
                'withdrawal_id'=>$withdraw->id,
                'status' => 2
            ]);

            //绑定提现记录
            $withdraw->commissions()->attach($commissionIds);
            DB::commit();
            //发送通知
            WithdrawalsApplyEvent::dispatch($withdraw);

            return $this->success('ok',$withdraw);
        } catch (ModelNotFoundException) {
            DB::rollBack();
            return $this->jsonResponse(1, '获取用户钱包失败');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->jsonResponse(1, $e->getMessage());
        }
    }

    public function deleteWithdraw(Request $request,$id){
        try {
            DB::beginTransaction();
            $detail = PartnerCommission::find($id);
            $withdrawal_id = $detail->withdrawal_id;
            if(in_array($detail->status,[0,5])){
                return $this->failure('记录不可操作');
            }
            PartnerWithdrawal::where('id',$detail->withdrawal_id)->update(['amount' => DB::raw("amount - $detail->amount"),]);
            PartnerCommission::where('id',$id)->update(['withdrawal_id'=>null,'status'=>1]);

            if($detail->status == 2){
                PartnerWallet::where('user_id', $this->user->id)->update([
                    'balance' => DB::raw("balance + $detail->amount"),
                    'withdrawn_amount' => DB::raw("withdrawn_amount - $detail->amount")
                ]);
            }
            //如果没有了都删除
            $exists_withdraw = PartnerCommission::where('withdrawal_id',$withdrawal_id)->exists();
            if(!$exists_withdraw){
                PartnerWithdrawal::where('id',$withdrawal_id)->delete();
            }
            DB::commit();
            return $this->success('ok');
        }catch (\Exception $e) {
            DB::rollBack();
            AddErrorLog::dispatch('deleteWithdraw file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('删除失败');
        }
    }
    public function getAccount(Request $request){
        try {
            $type = $request->input('type',0);
            $list = PartnerAccount::where('user_id',$this->user->id)->where('type',$type)->get();
            return $this->success('ok',$list);
        }catch (\Exception $e) {
            AddErrorLog::dispatch('getAccount file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }
    public function updateWithdraw(Request $request,$id){
        try {
            $detail = PartnerWithdrawal::findOrFail($id);
            $bill_pic = $request->input('bill_pic');
            $detail->bill_pic = $bill_pic;
            $detail->save();
            return $this->success('ok');
        }catch (\Exception $e) {
            AddErrorLog::dispatch('uploadBillPic file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('上传失败');
        }
    }
    public function getWithdraws(Request $request)
    {
        $withdrawals = PartnerWithdrawal::where('user_id', $this->user->id)
            ->orderByDesc('id')
            ->paginate();
        $withdrawals->each(function ($withdrawal) {
            $withdrawal->rollback_amount = bcsub($withdrawal->amount, $withdrawal->send_amount, 2);
        });
        return $this->success('ok', $withdrawals);
    }
}
