<?php


namespace app\models\tree;


use app\models\user\User;
use app\models\user\UserBill;
use crmeb\basic\BaseModel;
use crmeb\traits\ModelTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\model\relation\HasMany;
use think\model\relation\HasOne;

class TreeRecommend extends BaseModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 模型名称
     * @var string
     */
    protected $name = 'tree_recommend';

    private static $layers;
    private static $get;

    use ModelTrait;


    public function __construct(array $data = [])
    {
        parent::__construct($data);
        self::$layers = sys_config('group_layer', 12);
        self::$get = sys_config('group_award', 135);
    }

    public function user(): HasOne
    {
        return $this->HasOne(User::class, 'uid', 'uid');
    }

    /**
     * 排点
     * @param int $uid
     * @param int $spread_uid
     * @return array|bool|int[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getTreePoint(int $spread_uid = 0, $way = 1)
    {
        if (!self::count()) {
            return [0, 1];//父节点,线路
        }
        $parent_last_point = self::where('uid', $spread_uid)->order('add_time', 'desc')->find();
        if ($spread_uid == 0) {
            $parent_last_point = self::order('add_time', 'asc')->find();
        }
        while (!$parent_last_point) {
            $spread_uid = User::where('uid', $spread_uid)->value('spread_uid');
            if (!$spread_uid)
                $parent_last_point = self::order('add_time', 'asc')->find();
            else
                $parent_last_point = self::where('uid', $spread_uid)->order('add_time', 'desc')->find();
        }
        while (1) {
            //看线
            $res = self::where('way', $way)->where('parent_id', $parent_last_point['id'])->find();
            if ($res) {
                for ($i = 0; ; $i++) {
                    if ($i == self::$layers - 1) {
                        $spreads = User::where('spread_uid', $parent_last_point['uid'])->column('uid');
                        if (count(self::where('uid', 'in', $spreads)->group('uid')->field('uid,COUNT(uid)')->select()) + count(self::where('uid', $parent_last_point['uid'])->select()) - 1 >= $way) {
                            break;
                        }
                    }
                    $id = $res['id'];
                    $res = self::where('way', 1)->where('parent_id', $id)->find();
                    if (!$res) {
                        return [$id, 1];
                    }
                }
                $way++;
            } else {
                return [$parent_last_point['id'], $way];
            }
        }
    }

    /**
     * 进场
     * @param int $uid
     * @param int $spread_uid
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function insertTree(int $uid, int $spread_uid = 0, $way = 1): bool
    {
        $res = self::getTreePoint($spread_uid, $way);
        if (!$res) return self::setErrorInfo(self::getErrorInfo());
        list($tree_leader, $way) = $res;
        self::beginTrans();
        try {
            $res = self::create([
                'uid' => $uid,
                'parent_id' => $tree_leader,
                'way' => $way,
                'add_time' => time(),
            ]);
            $res = $res && self::sendToUper($tree_leader, $res->id);
            self::checkTrans($res);
            if ($res) {
                return true;
            } else {
                return self::setErrorInfo('加入失败');
            }
        } catch (\Exception $e) {
            self::rollbackTrans();
            return self::setErrorInfo($e->getMessage());
        }
    }

    /**
     * 发奖
     * @param int $point
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function sendToUper(int $point, $link_id): bool
    {
        $info = self::where('id', $point)->find();
        $res = true;
        $i = 0;
        while ($info && $i < self::$layers) {
            $info->get += (float)self::$get;
            $res = $res && $info->save();
            $balance = User::where('uid', $info['uid'])->value('brokerage_price');
            $res = $res && UserBill::income('市场分红', $info['uid'], 'now_money', 'brokerage', self::$get, $link_id, $balance + self::$get, '下级用户参与分红,获得分红' . self::$get);
            $res = $res && User::where('uid', $info['uid'])->inc('brokerage_price', self::$get)->update();
            $info = self::where('id', $info['parent_id'])->find();
            $i++;
        }
        return $res;
    }
}