<?php

namespace app\common\logic\finance;

use app\adminapi\logic\ConfigLogic;
use app\common\enum\user\AccountLogEnum;
use app\common\logic\BaseLogic;
use app\common\model\Company;
use app\common\model\company\CompanyAccountLog;
use app\common\model\user\User;
use app\common\model\user\UserAccountLog;
use app\common\model\user\Withdraw;
use think\Exception;
use think\facade\Db;
use think\facade\Log;

class WithdrawLogic extends BaseLogic
{
    public static function audit($params)
    {
        try {
            $withDrawInfo = Withdraw::find(['id'=>$params['id']]);
            Log::info(['提现申请审核-申请单', $withDrawInfo]);
            if (empty($withDrawInfo)) {
                throw new Exception('数据不存在');
            }
            if ($withDrawInfo->status !== 0) {
                throw new Exception('状态异常,当前申请已审核');
            }

            $userInfo = User::find(['id'=>$withDrawInfo['user_id']]);
            Log::info(['提现申请审核-申请人账户', $userInfo]);
            if (empty($userInfo)) {
                throw new Exception('账户异常,提现账户不存在');
            }
            if ($userInfo['admin_id'] === 0) {
                throw new Exception('账户异常,该账户没有提现权限');
            }
            $companyInfo = Company::find($userInfo['company_id']);
            Log::info(['提现申请审核-公司', $userInfo]);
            if (empty($companyInfo)) {
                throw new Exception('账户异常,提现账户没有关联公司');
            }

            // 拒绝通过审核,记录备注原因
            if ($params['status'] == 2) {
                Withdraw::where(['id'=>$withDrawInfo['id']])->update(['status'=>2, 'deny_desc'=>$params['deny_desc'] ?? '']);
                return true;
            }

            if (empty($params['transfer_voucher'])) {
                throw new Exception('请上传转账凭证');
            }

            Db::startTrans();
            $endCycle = $withDrawInfo['transfer_end_cycel']; // 提现周期截止时间戳

            /**
             * 1.扣除 公司账户余额 和 添加公司账户余额变动记录
             * 2.扣除公司内用户的余额(在本次提现周期内增加的金额总和)和用户账户变动记录,并且将用户周期内的账户变动记录变更为已提现状态
             *
             */

            // 1.扣除公司账户余额
            $amount = $withDrawInfo['amount']; // 提现金额
            $leftMoney = bcsub($companyInfo['company_money'], $amount, 2); // 提现后剩余金额
            if ($leftMoney < 0) {
                throw new Exception('公司账户余额不足');
            }
            $companyInfo->save(['company_money'=>$leftMoney]);

            $companyAccountLog = [
                'sn' => generate_sn(UserAccountLog::class, 'sn', 20),
                'company_id' => $companyInfo['id'],
                'change_object' => CompanyAccountLog::COMPANY_MONEY, //变动对象
                'change_type' => CompanyAccountLog::WITHDRAW_DEC_DEPOSIT, //变动类型
                'action' => CompanyAccountLog::DEC, //1-增加 2-减少
                'left_amount' => $leftMoney, //变动后数量
                'change_amount' => $amount, //变动数量
                'remark' => '减少原因:提现',
                'status' => 1,
            ];
            // 添加公司账户余额变动记录
            CompanyAccountLog::create($companyAccountLog);

            // 2.扣除公司内用户在本次提现周期内增加的金额总和 和 用户账户变动记录,并且将周期内的用户的账户变动记录变更为已提现状态
            $companyUserList = User::where(['company_id'=>$companyInfo['id']])->select();
            foreach ($companyUserList as $user) {
                $tempUserMoneySycleTotal = 0;
                $tempUserLeftMoney = 0;
                // 本次提现周期内增加的金额总和    周期内用户状态已完成的 变动类型为任务收益金额增加 动作为增加 未提现状态 的变动金额之和
                $tempUserMoneySycleTotal = UserAccountLog::where(['user_id'=>$user->id, 'status'=>1, 'action'=>1, 'change_type'=>202, 'is_withdraw'=>0])->where('create_time','<', $endCycle)->sum('change_amount');
                $tempUserLeftMoney = bcsub($user->user_money,$tempUserMoneySycleTotal, 2);
                if( $tempUserLeftMoney < 0 ){
                    throw new Exception('账户异常,用户余额不足,user_id:'.$user->id.",扣除金额:".$tempUserMoneySycleTotal);
                }
                // 扣除用户余额
                $user->save(['user_money'=>$tempUserLeftMoney]);
                // 用户账户变动记录
                $data = [
                    'sn' => generate_sn(UserAccountLog::class, 'sn', 20),
                    'user_id' => $user->id,
                    'company_id'=> $user->company_id,
                    'change_object' => AccountLogEnum::UM,
                    'change_type' => AccountLogEnum::UM_DEC_WITHDRAW,
                    'action' => AccountLogEnum::DEC,
                    'left_amount' => $tempUserLeftMoney,
                    'change_amount' => $tempUserMoneySycleTotal,
                    'source_sn' => '',
                    'remark' => '减少原因:公司提现',
                    'extra' => '',
                    'status'=> 1,
                    'is_withdraw'=> 1
                ];
                UserAccountLog::create($data);
                // 将用户周期内的账户变动记录变更为已提现状态
                UserAccountLog::where(['user_id'=>$user->id, 'status'=>1, 'action'=>1, 'change_type'=>202, 'is_withdraw'=>0])->where('create_time','<', $endCycle)->update(['is_withdraw'=>1]);
            }

            // 重置公司可提现截止日期 上一次截止日期 + 长期周期天数
            $dictData = ConfigLogic::getDictTypeValueByType('withdraw_cycle');
            $cycle = $dictData['withdraw_cycle_long']['value'];  // 数据字典-提现周期 单位:天数
            $withdrawDeadline = $endCycle + $cycle * 24 * 60 * 60;
            $companyInfo->save(['withdraw_deadline' => $withdrawDeadline]);

            // 更新状态,保存转账凭证
            Withdraw::where(['id'=>$withDrawInfo['id']])->update(['status'=>3, 'transfer_voucher'=>$params['transfer_voucher']]);


            Db::commit();
            return true;
        } catch (Exception $exception) {
            Db::rollback();
            self::setError($exception->getMessage());
            return false;
        }

    }
}