<?php

namespace app\common\repositories\user;

use app\common\dao\user\UserSignGongxianDao;
use app\common\enum\user\UserSignGongxianEnum;
use app\common\repositories\BaseRepository;
use app\common\repositories\store\order\StoreOrderRepository;
use app\entity\data\user\UserEntity;
use app\entity\data\user\UserSignGongxianEntity;
use think\db\exception\DbException;
use think\exception\ValidateException;

class UserSignGongxianRepository extends BaseRepository
{
    public function __construct(UserSignGongxianDao $dao)
    {
        $this->dao = $dao;
    }

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

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

    /**
     * @param string $orderType
     * @param array $orderIdList
     * @return UserSignGongxianEntity[]
     */
    public function getUserSignGongxianEntityListByOrderIdListAndPending(string $orderType, array $orderIdList): array
    {
        return $this->dao->getUserSignGongxianEntityListByOrderIdListAndPending($orderType, $orderIdList);
    }

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

    /**
     * 写入贡献值记录
     * @param UserSignGongxianEntity $userSignGongxianEntity
     * @return UserSignGongxianEntity
     */
    public function createByEntity(UserSignGongxianEntity $userSignGongxianEntity): UserSignGongxianEntity
    {
        $result = $this->dao->create($userSignGongxianEntity->toUnderlineArray())->toArray();
        /** @var UserSignGongxianEntity $entity */
        $entity = UserSignGongxianEntity::newInstance($result);
        return $entity;
    }

    /**
     * 添加贡献值记录
     * @param int $uid
     * @param int $type
     * @param float $number
     * @param string $mark
     * @param string $orderType
     * @param string $orderId
     * @return UserSignGongxianEntity
     */
    public function addUserSingGongxian(int $uid, int $type, float $number, string $mark = '', string $orderType = '', string $orderId = ''): UserSignGongxianEntity
    {
        $merId = 0;
        if (!empty($orderType)) {
            if (!empty($orderId)) {
                if ($orderType == UserSignGongxianEnum::ORDER_TYPE['Platform']['code']) {
                    /** @var StoreOrderRepository $storeOrderRepository */
                    $storeOrderRepository = app()->make(StoreOrderRepository::class);
                    $storeOrderEntity = $storeOrderRepository->getStoreOrderEntityByOrderId((int)$orderId);
                    if (empty($storeOrderEntity->getOrderId())) {
                        throw new ValidateException('未查询到订单信息');
                    }
                    $merId = $storeOrderEntity->getMerId();
                }
            }
        }

        /** @var UserSignGongxianEntity $userSignGongxianEntity */
        $userSignGongxianEntity = UserSignGongxianEntity::newInstance();
        $userSignGongxianEntity->setUid($uid)
            ->setType($type)
            ->setNumber($number)
            ->setMark($mark)
            ->setOrderType($orderType)
            ->setOrderId($orderId)
            ->setMerId($merId)
            ->setAddtime(time())
            ->setStatus(UserSignGongxianEnum::STATUS['PendingConfirmation']['code']);

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

    /**
     * 将 贡献值 直推贡献值 记录设置为生效状态 并对用户的 贡献值 直推贡献值 字段进行增减
     * @param array $idList
     * @return array
     */
    public function executeByIdList(array $idList): array
    {
        $userSignGongxianEntityList = $this->getUserSignGongxianEntityListByIdList($idList);
        $userIdList = [];

        // 忽略 已经生效的 记录
        $userSignGongxianEntityList = array_filter($userSignGongxianEntityList, function ($entity) use (&$userIdList) {
            // 积分数据不为空 用户不为空 状态属于待结算 并且结算字段为空
            if ((!empty($entity->getId()) && !empty($entity->getUid()) && ($entity->getStatus() == UserSignGongxianEnum::STATUS['PendingConfirmation']['code']) && empty($entity->getSettlementTime()))) {
                $userIdList[] = $entity->getUid();
                return true;
            }
            return false;
        });

        if (!empty($userSignGongxianEntityList)) {
            // 获取用户 映射信息
            /** @var UserRepository $userRepository */
            $userRepository = app()->make(UserRepository::class);
            /** @var UserEntity[] $userEntityMapByUid */
            $userEntityMapByUid = [];
            if (!empty($userIdList)) {
                $userEntityMapByUid = $userRepository->getUserEntityMapByUidList($userIdList);
            }

            /** @var UserEntity[] $updateUserEntityList */
            $updateUserEntityList = [];
            /** @var UserSignGongxianEntity[] $updateUserScoreEntityList */
            $updateUserScoreEntityList = [];
            foreach ($userSignGongxianEntityList as $userSignGongxianEntity) {

                $userEntity = $userEntityMapByUid[$userSignGongxianEntity->getUid()];
                if (empty($userEntity) || empty($userEntity->getUid())) {
                    throw new ValidateException("未查询到用户信息(GongxianId:{$userSignGongxianEntity->getId()})");
                }

                // 组建 更新 用户信息
                if (isset($updateUserEntityList[$userEntity->getUid()])) {
                    $updateUserEntity = $updateUserEntityList[$userEntity->getUid()];
                } else {
                    /** @var UserEntity $updateUserEntity */
                    $updateUserEntity = UserEntity::newInstance();
                    $updateUserEntity
                        ->setUid($userEntity->getUid())
                        ->setContribute($userEntity->getContribute())
                        ->setPerContribute($userEntity->getPerContribute());
                }
                // 组建 账单 记录
                if (isset($updateUserScoreEntityList[$userSignGongxianEntity->getId()])) {
                    $updateUserSignGongxianEntity = $updateUserScoreEntityList[$userSignGongxianEntity->getId()];
                } else {
                    /** @var UserSignGongxianEntity $updateUserSignGongxianEntity */
                    $updateUserSignGongxianEntity = UserSignGongxianEntity::newInstance();
                    // 更新 账单记录 状态
                    $updateUserSignGongxianEntity
                        ->setId($userSignGongxianEntity->getId())
                        ->setStatus(UserSignGongxianEnum::STATUS['Valid']['code'])
                        ->setSettlementTime(date('Y-m-d H:i:s'));
                }

                if ($userSignGongxianEntity->getType() == UserSignGongxianEnum::TYPE['Consume']['code']) {
                    // 消耗
                    if (strpos($userSignGongxianEntity->getMark(), '购买') !== false) {
                        $updateUserEntity->setContribute(bcsub($updateUserEntity->getContribute(), $userSignGongxianEntity->getNumber(), 2));
                        if ($updateUserEntity->getContribute() < 0.00) {
                            throw new ValidateException('用户贡献值不足');
                        }
                        $updateUserSignGongxianEntity->setSurplus($updateUserEntity->getContribute());
                    } else if (strpos($userSignGongxianEntity->getMark(), '推广') !== false) {
                        $updateUserEntity->setPerContribute(bcsub($updateUserEntity->getPerContribute(), $userSignGongxianEntity->getNumber(), 2));
                        if ($updateUserEntity->getPerContribute() < 0.00) {
                            throw new ValidateException('用户推广贡献值不足');
                        }
                        $updateUserSignGongxianEntity->setSurplus($updateUserEntity->getPerContribute());
                    }
                } else {
                    if (strpos($userSignGongxianEntity->getMark(), '购买') !== false) {
                        $updateUserEntity->setContribute(bcadd($updateUserEntity->getContribute(), $userSignGongxianEntity->getNumber(), 2));
                        $updateUserSignGongxianEntity->setSurplus($updateUserEntity->getContribute());
                    } else if (strpos($userSignGongxianEntity->getMark(), '推广') !== false) {
                        $updateUserEntity->setPerContribute(bcadd($updateUserEntity->getPerContribute(), $userSignGongxianEntity->getNumber(), 2));
                        $updateUserSignGongxianEntity->setSurplus($updateUserEntity->getPerContribute());
                    }
                }

                $updateUserEntityList[$userSignGongxianEntity->getUid()] = $updateUserEntity;
                $updateUserScoreEntityList[$userSignGongxianEntity->getId()] = $updateUserSignGongxianEntity;
            }
            if (!empty($updateUserEntityList)) {
                $userRepository->batchUpdateUserDataByDataList(
                    array_map(function (UserEntity $updateUserEntity) {
                        return $updateUserEntity->toUnderlineArray();
                    }, $updateUserEntityList)
                );
            }

            if (!empty($updateUserScoreEntityList)) {
                $this->batchUpdateUserSignGongxianDataByDataList(
                    array_map(function (UserSignGongxianEntity $updateUserSignGongxianEntity) {
                        return $updateUserSignGongxianEntity->toUnderlineArray();
                    }, $updateUserScoreEntityList)
                );
            }
        }
        return $idList;
    }

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