<?php



namespace app\common\repositories\user;


use app\common\dao\user\UserBrokerageDao;
use app\common\model\user\User;
use app\common\model\user\UserBrokerage;
use app\common\repositories\BaseRepository;
use think\facade\Db;

/**
 * @mixin UserBrokerageDao
 */
class UserBrokerageRepository extends BaseRepository
{

    public const BROKERAGE_RULE_TYPE = ['spread_user', 'pay_money', 'pay_num', 'spread_money', 'spread_pay_num'];

    public function __construct(UserBrokerageDao $dao)
    {
        $this->dao = $dao;
    }

    public function getList(array $where, $page, $limit)
    {
        $query = $this->dao->search($where)->order('brokerage_level DESC,create_time DESC');
        $count = $query->count();
        $list = $query->page($page, $limit)->select();
        return compact('list', 'count');
    }

    public function getNextLevel($level)
    {
        return $this->search(['next_level' => $level])->order('brokerage_level ASC,create_time DESC')->find();
    }

    public function options()
    {
        return $this->dao->search([])->field('brokerage_level as value,brokerage_name as label')->order('brokerage_level ASC,create_time DESC')->select();
    }

    public function all()
    {
        return $this->dao->search([])->order('brokerage_level ASC,create_time DESC')->select();
    }

    public function inc(User $user, $type, $inc)
    {
        $nextLevel = $this->getNextLevel($user->brokerage_level);
        if (!$nextLevel) return false;
        $make = app()->make(UserBillRepository::class);
        $bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]);
        if ($bill) {
            $bill->number = bcadd($bill->number, $inc, 2);
            $bill->save();
        } else {
            $make->incBill($user->uid, 'sys_brokerage', $type, [
                'number' => $inc,
                'title' => $type,
                'balance' => 0,
                'status' => 0,
                'link_id' => $nextLevel->user_brokerage_id
            ]);
        }

        return $this->checkLevel($user, $nextLevel);
    }

    public function checkLevel(User $user, UserBrokerage $nextLevel)
    {
        $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
            ->column('number', 'type');
        foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
            if (!isset($info[$k]) && $rule['num'] > 0) return false;
            if ($rule['num'] > 0 && $rule['num'] > $info[$k]) return false;
        }
        $nextLevel->user_num++;
        Db::transaction(function () use ($nextLevel, $user) {
            $nextLevel->save();
            if ($user->brokerage && $user->brokerage->user_num > 0) {
                $user->brokerage->user_num--;
                $user->brokerage->save();
            }
            $user->brokerage_level = $nextLevel->brokerage_level;
            $user->save();
        });
        return true;
    }

    public function getLevelRate(User $user, UserBrokerage $nextLevel)
    {
        $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
            ->column('number', 'type');
        $brokerage_rule = $nextLevel['brokerage_rule'];
        foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
            if ($rule['num'] <= 0) {
                unset($brokerage_rule[$k]);
                continue;
            }
            if (!isset($info[$k])) {
                $rate = 0;
            } else if ($rule['num'] > $info[$k]) {
                $rate = bcdiv($info[$k], $rule['num'], 2) * 100;
            } else {
                $rate = 100;
            }
            $brokerage_rule[$k]['rate'] = $rate;
            $brokerage_rule[$k]['task'] = (float)(min($info[$k] ?? 0, $rule['num']));
        }
        return $brokerage_rule;
    }

}