<?php

namespace app\common\dao\shared;

use app\common\dao\BaseDao;
use app\common\enum\CommonEnum;
use app\common\model\BaseModel;
use app\common\model\shared\SharedProsperityUser;
use app\entity\data\shared\SharedProsperityUserEntity;
use think\db\exception\DbException;

class SharedProsperityUserDao extends BaseDao
{

    /**
     * @return BaseModel
     */
    protected function getModel(): string
    {
        return SharedProsperityUser::class;
    }

    /**
     * @param array $idList
     * @return SharedProsperityUserEntity[]
     */
    public function getSharedProsperityUserEntityListByIdList(array $idList): array
    {
        $entityList = [];
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $dataRes = $model::getDB()
                ->whereIn('id', $idList)
                ->select()
                ->toArray();
            if (!empty($dataRes)) {
                $entityList = array_map(function ($data) {
                    return SharedProsperityUserEntity::newInstance($data);
                }, $dataRes);
            }
        } catch (\Exception $e) {

        }
        return $entityList;
    }

    /**
     * @param array $userIdList
     * @return SharedProsperityUserEntity[]
     */
    public function getSharedProsperityUserEntityListByUserIdList(array $userIdList): array
    {
        $entityList = [];
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $dataRes = $model::getDB()
                ->whereIn('user_id', $userIdList)
                ->select()
                ->toArray();
            if (!empty($dataRes)) {
                $entityList = array_map(function ($data) {
                    return SharedProsperityUserEntity::newInstance($data);
                }, $dataRes);
            }
        } catch (\Exception $e) {

        }
        return $entityList;
    }

    /**
     * @param int $parentId
     * @return SharedProsperityUserEntity[]
     */
    public function getSharedProsperityUserEntityListByParentId(int $parentId): array
    {
        $entityList = [];
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $dataRes = $model::getDB()
                ->where('parent_id', '=', $parentId)
                ->select()
                ->toArray();
            if (!empty($dataRes)) {
                $entityList = array_map(function ($data) {
                    return SharedProsperityUserEntity::newInstance($data);
                }, $dataRes);
            }
        } catch (\Exception $e) {

        }
        return $entityList;
    }

    /**
     * 获取所有直推用户（不分页）
     * @param int $userId
     * @return array
     * @author 史晨
     * @date 2026/2/9 09:35
     */
    public function getDirectByUserId(int $userId): array
    {
        $list = [];
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $list = $model::getDB()
                ->where('parent_id', $userId)
                ->select()
                ->toArray();
        } catch (\Exception $e) {

        }
        return $list;
    }

    /**
     * 递归获取团队所有下级用户ID（可选择是否包含自己）
     * @param int $userId
     * @param bool $includeSelf 是否包含自己
     * @param int $hierarchy 层级限制，0表示不限制，>0表示限制层级
     * @return int[]
     */
    public function getAllSubordinateUserIds(int $userId, bool $includeSelf = false, int $hierarchy = CommonEnum::ORDER_EARNING_ALLOCATION['SharedProsperity']['Hierarchy']['code']): array
    {
        $allIds = [];
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $getRecursiveChildren = function ($parentId, $currentLevel = 1) use (&$getRecursiveChildren, $model, $hierarchy) {
                // 如果设置了层级限制且当前层级超过限制，则停止递归
                if ($hierarchy > 0 && $currentLevel > $hierarchy) {
                    return [];
                }
                $children = $model::getDB()
                    ->where('parent_id', $parentId)
                    ->column('user_id');
                $allChildren = [];
                foreach ($children as $childId) {
                    $allChildren[] = $childId;
                    $allChildren = array_merge($allChildren, $getRecursiveChildren($childId, $currentLevel + 1));
                }
                return $allChildren;
            };
            $allIds = $getRecursiveChildren($userId);
            if ($includeSelf) {
                array_unshift($allIds, $userId);
            }
        } catch (\Exception $e) {
            // 记录日志或忽略
        }
        return $allIds;
    }

    /**
     * 获取团队所有下级用户PV总和（不包括自己）
     * @param int $userId
     * @return float
     */
    public function getTeamPvSum(int $userId, int $hierarchy = CommonEnum::ORDER_EARNING_ALLOCATION['SharedProsperity']['Hierarchy']['code']): float
    {
        $userIds = $this->getAllSubordinateUserIds($userId, false, $hierarchy);
        if (empty($userIds)) {
            return 0.0;
        }
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $sum = $model::getDB()
                ->whereIn('user_id', $userIds)
                ->sum('pv');
            return (float)$sum;
        } catch (\Exception $e) {
            return 0.0;
        }
    }

    /**
     * 获取团队所有下级用户PV总和（包括自己）
     * @param int $userId
     * @return float
     */
    public function getTeamPvSumWithSelf(int $userId, $self = false): float
    {
        $userIds = $this->getAllSubordinateUserIds($userId, $self);
        if (empty($userIds)) {
            return 0.0;
        }
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $sum = $model::getDB()
                ->whereIn('user_id', $userIds)
                ->sum('pv');
            return (float)$sum;
        } catch (\Exception $e) {
            return 0.0;
        }
    }

    /**
     * 批量更新
     * @param $dataList
     * @return array
     */
    public function saveAll($dataList): array
    {
        try {
            return $this->getModel()::getInstance()->allowField(array_keys(reset($dataList)))->saveAll($dataList)->toArray();
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 根据用户ID更新记录
     * @param int $userId
     * @param array $data
     * @return int
     */
    public function updateByUserId(int $userId, array $data): int
    {
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            return $model::getDB()->where('user_id', $userId)->update($data);
        } catch (\Exception $e) {
            return 0;
        }
    }

    public function updateRewardByUserId($userId, $field, $value)
    {
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            return $model::getDB()->where('user_id', $userId)->inc($field,$value)->update();
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 按合伙人等级分组获取用户
     * @return array [partner_level => [user_id1, user_id2, ...]]
     */
    public function getUserGroupByPartnerLevel(): array
    {
        try {
            /** @var SharedProsperityUser $model */
            $model = $this->getModel();
            $dataRes = $model::getDB()
                ->field('partner_level, user_id')
                ->select()
                ->toArray();

            $grouped = [];
            foreach ($dataRes as $row) {
                $level = $row['partner_level'];
                if (!isset($grouped[$level])) {
                    $grouped[$level] = [];
                }
                $grouped[$level][] = $row['user_id'];
            }
            return $grouped;
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * @return array|void
     * @author 史晨
     * @date 2026/2/27 09:32
     * 后台用户列表
     */
    public function adminList($where,$page)
    {
        /** @var SharedProsperityUser $model */
        $model = $this->getModel();
        try {
            $list = $model::getDB()
                ->where($where)
                ->with([
                    'user' => function ($query) {
                        $query->field('uid,avatar,nickname,account');
                    },
                    'parent' => function ($query) {
                        $query->field('uid,avatar,nickname,account');
                    },
                    'group' => function ($query) {
                        $query->field('group_id,user_id');
                    }
                ])
                ->paginate(['page' => $page, 'list_rows' => 20])
                ->toArray();
            return $list;
        } catch (DbException $e) {
            return [];
        }
    }
}
