<?php

namespace app\common\repositories\shared;

use app\common\dao\shared\SharedProsperityRewardRecordDao;
use app\common\dao\shared\SharedProsperityUserDao;
use app\common\enum\shared\SharedProsperityRewardRecordEnum;
use app\common\repositories\BaseRepository;
use app\common\repositories\store\order\StoreOrderRepository;
use app\entity\data\shared\SharedProsperityRewardRecordEntity;
use app\entity\data\shared\SharedProsperityUserEntity;
use think\db\exception\DbException;
use think\exception\ValidateException;

class SharedProsperityRewardRecordRepository extends BaseRepository
{

    protected $dao;

    /**
     * SharedProsperityRewardRecordRepository constructor.
     * @param SharedProsperityRewardRecordDao $dao
     */
    public function __construct(SharedProsperityRewardRecordDao $dao)
    {
        $this->dao = $dao;
    }

    /**
     * @param int $id
     * @return SharedProsperityRewardRecordEntity
     */
    public function getSharedProsperityRewardRecordEntityById(int $id): SharedProsperityRewardRecordEntity
    {
        $entityList = $this->getSharedProsperityRewardRecordEntityListByIdList([$id]);
        $entity = array_shift($entityList);
        if ($entity instanceof SharedProsperityRewardRecordEntity) {
            return $entity;
        } else {
            /** @var SharedProsperityRewardRecordEntity */
            return SharedProsperityRewardRecordEntity::newInstance();
        }
    }

    /**
     * @param array $idList
     * @return SharedProsperityRewardRecordEntity[]
     */
    public function getSharedProsperityRewardRecordEntityListByIdList(array $idList): array
    {
        return $this->dao->getSharedProsperityRewardRecordEntityListByIdList($idList);
    }

    public function create($data)
    {
        return $this->dao->create($data);
    }

    /**
     * @param SharedProsperityRewardRecordEntity $sharedProsperityRewardRecordEntity
     * @return SharedProsperityRewardRecordEntity
     */
    public function createByEntity(SharedProsperityRewardRecordEntity $sharedProsperityRewardRecordEntity): SharedProsperityRewardRecordEntity
    {
        $result = $this->create($sharedProsperityRewardRecordEntity->toUnderlineArray())->toArray();
        /** @var SharedProsperityRewardRecordEntity $entity */
        $entity = SharedProsperityRewardRecordEntity::newInstance($result);
        return $entity;
    }

    /**
     * @param $id
     * @param $data
     * @return int
     */
    public function update($id, $data): int
    {
        try {
            return $this->dao->update($id, $data);
        } catch (DbException $e) {
            return 0;
        }
    }

    /**
     * @param SharedProsperityRewardRecordEntity $sharedProsperityRewardRecordEntity
     * @return SharedProsperityRewardRecordEntity
     */
    public function updateByEntity(SharedProsperityRewardRecordEntity $sharedProsperityRewardRecordEntity): SharedProsperityRewardRecordEntity
    {
        if (empty($sharedProsperityRewardRecordEntity->getId())) {
            return SharedProsperityRewardRecordEntity::newInstance();
        }
        $result = $this->update($sharedProsperityRewardRecordEntity->getId(), $sharedProsperityRewardRecordEntity->toUnderlineArray());
        if ($result > 0) {
            return $this->getSharedProsperityRewardRecordEntityById($sharedProsperityRewardRecordEntity->getId());
        }
        return SharedProsperityRewardRecordEntity::newInstance();
    }

    /**
     * 添加 共富体系奖励记录
     * @param int $uid
     * @param int $type
     * @param int $pm
     * @param float $number
     * @param int $typeShop
     * @param string $orderSn
     * @param string $remark
     * @return SharedProsperityRewardRecordEntity
     */
    public function addSharedProsperityRewardRecord(int $uid, int $type, int $pm, float $number, int $typeShop = 0, string $orderSn = '', string $remark = ''): SharedProsperityRewardRecordEntity
    {
        if ($typeShop == SharedProsperityRewardRecordEnum::TYPE_SHOP['Platform']['code']) {
            /** @var StoreOrderRepository $storeOrderRepository */
            $storeOrderRepository = app()->make(StoreOrderRepository::class);
            $storeOrderEntity = $storeOrderRepository->getStoreOrderEntityByOrderSn($orderSn);
            if (empty($storeOrderEntity->getOrderId())) {
                throw new ValidateException('未查询到订单信息');
            }
        }

        /** @var SharedProsperityRewardRecordEntity $sharedProsperityRewardRecordEntity */
        $sharedProsperityRewardRecordEntity = SharedProsperityRewardRecordEntity::newInstance();
        $sharedProsperityRewardRecordEntity->setUserId($uid)
            ->setType($type)
            ->setPm($pm)
            ->setNumber($number)
            ->setStatus(SharedProsperityRewardRecordEnum::STATUS['PENDING']['code'])
            ->setTypeShop($typeShop)
            ->setOrderSn($orderSn)
            ->setRemark($remark);

        return $this->createByEntity($sharedProsperityRewardRecordEntity);
    }

    /**
     * @param string $typeShop
     * @param array $orderSnList
     * @return SharedProsperityRewardRecordEntity[]
     */
    public function getSharedProsperityRewardRecordEntityListByOrderSnListAndPending(string $typeShop, array $orderSnList): array
    {
        return $this->dao->getSharedProsperityRewardRecordEntityListByOrderSnListAndPending($typeShop, $orderSnList);
    }

    /**
     * @param $dataList
     * @return array
     */
    public function batchUpdateSharedProsperityRewardRecordDataByDataList($dataList): array
    {
        return $this->dao->saveAll($dataList);
    }

    /**
     * 结算 共富体系奖励记录
     * @param array $idList
     * @return array
     */
    public function executeByIdList(array $idList): array
    {
        $sharedProsperityRewardRecordEntityList = $this->getSharedProsperityRewardRecordEntityListByIdList($idList);
        // 忽略 已经生效的 记录
        $sharedProsperityRewardRecordEntityList = array_filter($sharedProsperityRewardRecordEntityList, function ($entity) {
            return $entity->getStatus() != SharedProsperityRewardRecordEnum::STATUS['VALID']['code'];
        });

        if (!empty($sharedProsperityRewardRecordEntityList)) {
            // 获取所有记录的 归属人
            $userIdList = array_map(function ($sharedProsperityRewardRecordEntity) {
                return $sharedProsperityRewardRecordEntity->getUserId();
            }, $sharedProsperityRewardRecordEntityList);

            // 获取用户 映射信息
            /** @var SharedProsperityUserRepository $sharedProsperityUserRepository */
            $sharedProsperityUserRepository = app()->make(SharedProsperityUserRepository::class);
            /** @var SharedProsperityUserEntity[] $sharedProsperityUserEntityMapByUserId */
            $sharedProsperityUserEntityMapByUserId = [];
            if (!empty($userIdList)) {
                $sharedProsperityUserEntityMapByUserId = $sharedProsperityUserRepository->getSharedProsperityUserEntityMapByUserIdList($userIdList);
            }

            $updateSharedProsperityUserEntityList = [];
            $updateSharedProsperityRewardRecordEntityList = [];
            foreach ($sharedProsperityRewardRecordEntityList as $sharedProsperityRewardRecordEntity) {
                if (empty($sharedProsperityRewardRecordEntity->getId()) || empty($sharedProsperityRewardRecordEntity->getUserId())) {
                    // throw new ValidateException('无效的账单记录');
                    continue;
                }
                if (!empty($sharedProsperityRewardRecordEntity->getTakeTime())) {
                    throw new ValidateException("该奖励记录已更新，请勿重复操作({$sharedProsperityRewardRecordEntity->getId()})");
                }

                $sharedProsperityUserEntity = $sharedProsperityUserEntityMapByUserId[$sharedProsperityRewardRecordEntity->getUserId()];
                if (empty($sharedProsperityUserEntity) || empty($sharedProsperityUserEntity->getUserId())) {
                    throw new ValidateException("未查询到用户信息({$sharedProsperityRewardRecordEntity->getId()})");
                }

                // 更新 用户信息
                /** @var SharedProsperityUserEntity $updateSharedProsperityUserEntity */
                $updateSharedProsperityUserEntity = $updateSharedProsperityUserEntityList[$sharedProsperityUserEntity->getUserId()] ?? SharedProsperityUserEntity::newInstance();
                $updateSharedProsperityUserEntity
                    ->setId($sharedProsperityUserEntity->getId())
                    ->setUserId($sharedProsperityUserEntity->getUserId())
                    ->setPartnerLevel($sharedProsperityUserEntity->getPartnerLevel());

                // 更新 账单 记录
                /** @var SharedProsperityRewardRecordEntity $updateSharedProsperityRewardRecord */
                $updateSharedProsperityRewardRecord = $updateSharedProsperityRewardRecordEntityList[$sharedProsperityRewardRecordEntity->getId()] ?? SharedProsperityRewardRecordEntity::newInstance();
                // 更新 账单记录 状态
                $updateSharedProsperityRewardRecord
                    ->setId($sharedProsperityRewardRecordEntity->getId())
                    ->setStatus(SharedProsperityRewardRecordEnum::STATUS['VALID']['code'])
                    ->setTakeTime(date('Y-m-d H:i:s'));

                if ($sharedProsperityRewardRecordEntity->getType() == SharedProsperityRewardRecordEnum::TYPE['CONSUMER_STOCKS']['code']) {
                    // 消费股
                    if (is_null($updateSharedProsperityUserEntity->getConsumerStocks())) {
                        $updateSharedProsperityUserEntity->setConsumerStocks($sharedProsperityUserEntity->getConsumerStocks());
                    }
                    // 更新用户 佣金 信息
                    if ($sharedProsperityRewardRecordEntity->getPm() == SharedProsperityRewardRecordEnum::PM['EXPEND']['code']) {
                        if ($updateSharedProsperityUserEntity->getConsumerStocks() < $sharedProsperityRewardRecordEntity->getNumber()) {
                            throw new ValidateException('用户剩余消费股不足');
                        }
                        $updateSharedProsperityUserEntity->setConsumerStocks(bcsub($updateSharedProsperityUserEntity->getConsumerStocks(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    } else {
                        $updateSharedProsperityUserEntity->setConsumerStocks(bcadd($updateSharedProsperityUserEntity->getConsumerStocks(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    }
                    $updateSharedProsperityRewardRecord->setBalance($updateSharedProsperityUserEntity->getConsumerStocks());
                } else if ($sharedProsperityRewardRecordEntity->getType() == SharedProsperityRewardRecordEnum::TYPE['WITHDRAWAL_LIMIT']['code']) {
                    // 提现额度
                    if (is_null($updateSharedProsperityUserEntity->getWithdrawalLimit())) {
                        $updateSharedProsperityUserEntity->setWithdrawalLimit($sharedProsperityUserEntity->getWithdrawalLimit());
                    }
                    // 更新用户 佣金 信息
                    if ($sharedProsperityRewardRecordEntity->getPm() == SharedProsperityRewardRecordEnum::PM['EXPEND']['code']) {
                        if ($updateSharedProsperityUserEntity->getWithdrawalLimit() < $sharedProsperityRewardRecordEntity->getNumber()) {
                            throw new ValidateException('用户剩余提现额度不足');
                        }
                        $updateSharedProsperityUserEntity->setWithdrawalLimit(bcsub($updateSharedProsperityUserEntity->getWithdrawalLimit(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    } else {
                        $updateSharedProsperityUserEntity->setWithdrawalLimit(bcadd($updateSharedProsperityUserEntity->getWithdrawalLimit(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    }
                    $updateSharedProsperityRewardRecord->setBalance($updateSharedProsperityUserEntity->getWithdrawalLimit());
                } else if ($sharedProsperityRewardRecordEntity->getType() == SharedProsperityRewardRecordEnum::TYPE['PV']['code']) {
                    // PV 结算
                    if (is_null($updateSharedProsperityUserEntity->getPv())) {
                        $updateSharedProsperityUserEntity->setPv($sharedProsperityUserEntity->getPv());
                    }
                    // 更新用户 佣金 信息
                    if ($sharedProsperityRewardRecordEntity->getPm() == SharedProsperityRewardRecordEnum::PM['EXPEND']['code']) {
                        if ($updateSharedProsperityUserEntity->getPv() < $sharedProsperityRewardRecordEntity->getNumber()) {
                            throw new ValidateException('用户剩余PV不足');
                        }
                        $updateSharedProsperityUserEntity->setPv(bcsub($updateSharedProsperityUserEntity->getPv(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    } else {
                        $updateSharedProsperityUserEntity->setPv(bcadd($updateSharedProsperityUserEntity->getPv(), $sharedProsperityRewardRecordEntity->getNumber(), 2));
                    }
                    $updateSharedProsperityRewardRecord->setBalance($updateSharedProsperityUserEntity->getPv());
                }

                $updateSharedProsperityUserEntityList[$sharedProsperityUserEntity->getUserId()] = $updateSharedProsperityUserEntity;
                $updateSharedProsperityRewardRecordEntityList[$sharedProsperityRewardRecordEntity->getId()] = $updateSharedProsperityRewardRecord;
            }
            if (!empty($updateSharedProsperityUserEntityList)) {
                $sharedProsperityUserRepository->batchUpdateSharedProsperityUserDataByDataList(
                    array_map(function (SharedProsperityUserEntity $updateSharedProsperityUserEntity) {
                        return $updateSharedProsperityUserEntity->toUnderlineArray();
                    }, $updateSharedProsperityUserEntityList)
                );
            }

            if (!empty($updateSharedProsperityRewardRecordEntityList)) {
                $this->batchUpdateSharedProsperityRewardRecordDataByDataList(
                    array_map(function (SharedProsperityRewardRecordEntity $updateSharedProsperityRewardRecordEntity) {
                        return $updateSharedProsperityRewardRecordEntity->toUnderlineArray();
                    }, $updateSharedProsperityRewardRecordEntityList)
                );
            }
        }

        return $idList;
    }


    /**
     * 获取奖励记录分页列表，并返回统计数据
     * @param int $userId 用户ID
     * @param int $status 前端传入的状态：1=有效，0=待确定
     * @param int $page 页码
     * @param int $pageSize 每页数量，默认10
     * @return array
     */
    public function getRewardList($userId, $status, $page, $pageSize = 10)
    {
        $type = SharedProsperityRewardRecordEnum::TYPE['PV']['code'];
        if ($status == 1) {
            $statusCode = SharedProsperityRewardRecordEnum::STATUS['VALID']['code'];
        } else {
            $statusCode = SharedProsperityRewardRecordEnum::STATUS['PENDING']['code'];
        }
        $pm = 1; // 只查询获得（收入）
        // 获取分页列表
        $list = $this->dao->getRewardList($userId, $type, $statusCode, null, $pm, $page, $pageSize);

        // 计算统计数据
        $stats = $this->calculateRewardStats($userId);

        return [
            'list' => $list,
            'stats' => $stats,
        ];
    }

    /**
     * 计算奖励统计数据
     * @param int $userId
     * @return array
     */
    private function calculateRewardStats(int $userId): array
    {
        $type = SharedProsperityRewardRecordEnum::TYPE['PV']['code'];
        $pm = 1; // 获得

        // 1. 我的贡献值（有效）
        $myContribution = $this->dao->getRewardSum($userId, $type, SharedProsperityRewardRecordEnum::STATUS['VALID']['code'], null, $pm);
        // 2. 未生效贡献值（待确定）
        $pendingContribution = $this->dao->getRewardSum($userId, $type, SharedProsperityRewardRecordEnum::STATUS['PENDING']['code'], null, $pm);

        // 获取直推用户ID列表
        /** @var SharedProsperityUserDao $sharedProsperityUserDao */
        $sharedProsperityUserDao = app()->make(SharedProsperityUserDao::class);
        $directUserIds = array_column($sharedProsperityUserDao->getDirectByUserId($userId), 'user_id');

        // 3. 直推贡献值（直推用户的有效贡献总和）
        $directContribution = 0;
        if (!empty($directUserIds)) {
            $directContribution = $this->dao->getRewardSum($directUserIds, $type, SharedProsperityRewardRecordEnum::STATUS['VALID']['code'], null, $pm);
        }

        // 4. 小部门贡献值（需要区分大部门和小部门）
        // 获取团队划分
        /** @var SharedProsperityUserRepository $sharedProsperityUserRepository */
        $sharedProsperityUserRepository = app()->make(SharedProsperityUserRepository::class);
        $teamData = $sharedProsperityUserRepository->getTeam($userId);
        $smallDepartmentUserIds = array_column($teamData['small_department'] ?? [], 'user_id');
        $smallDepartmentContribution = 0;
        if (!empty($smallDepartmentUserIds)) {
            $smallDepartmentContribution = $this->dao->getRewardSum($smallDepartmentUserIds, $type, SharedProsperityRewardRecordEnum::STATUS['VALID']['code'], null, $pm);
        }

        return [
            'my_contribution' => (float) $myContribution,
            'pending_contribution' => (float) $pendingContribution,
            'direct_contribution' => (float) $directContribution,
            'small_department_contribution' => (float) $smallDepartmentContribution,
        ];
    }

    /**
     * @param $startTime
     * @param $endTime
     * @return array
     * @throws DbException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @author 史晨
     * @date 2026/2/10 14:07
     * 获取时间段内奖励列表
     */
    public function getListByTime($startTime, $endTime, $type)
    {
        return $this->dao->getListByTime($startTime, $endTime, $type);
    }
}
