<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\api\model\groupon;

use app\api\model\Goods as GoodsModel;
use app\api\model\groupon\Goods as GrouponGoodsModel;
use app\api\model\groupon\TaskUsers as TaskUsersModel;
use app\api\service\User as UserService;
use app\api\service\Goods as GoodsService;
use app\common\model\groupon\Task as TaskModel;
use app\common\enum\groupon\ActiveType as ActiveTypeEnum;
use app\common\enum\groupon\TaskStatus as TaskStatusEnum;
use cores\exception\BaseException;

/**
 * 拼团拼单模型
 * Class Task
 * @package app\api\model\groupon
 */
class Task extends TaskModel
{
    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'actual_people',
        'robot_people',
        'is_delete',
        'store_id',
        'create_time',
        'update_time',
    ];

    /**
     * 我的拼团列表
     * @return mixed|\think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getMyList()
    {
        // 当前登录用户ID
        $userId = UserService::getCurrentLoginUserId();
        // 砍价活动列表
        $list = $this->where('user_id', '=', $userId)
            ->where('is_delete', '=', 0)
            ->order(['create_time' => 'desc'])
            ->paginate(15);
        // 设置商品数据
        if (!$list->isEmpty()) {
            $list = GoodsService::setGoodsData($list, true, GoodsModel::getHidden(['goods_images']));
        }
        return $list;
    }

    /**
     * 获取指定商品的凑团记录
     * @param int $groupGoodsId 拼团商品ID
     * @param int $limit 限制的数量
     * @return array|\think\Collection|\think\db\BaseQuery[]
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getQuickJoinList(int $groupGoodsId, int $limit)
    {
        // 当前用户ID (凑团信息不能显示自己发起的团)
        $userId = UserService::getCurrentLoginUserId(false);
        // 查询列表数据
        $query = (new static)->getNewQuery();
//        $userId > 0 && $query->where('user_id', '<>', $userId);
        return $query->with(['user.avatar'])
            ->field(['(people - actual_people - robot_people) as surplus_people'])
            ->field(true)
            ->where('groupon_goods_id', '=', $groupGoodsId)
            ->where('end_time', '>=', time())
            ->where('status', '=', TaskStatusEnum::NORMAL)
            ->where('is_delete', '=', 0)
            ->order(['surplus_people' => 'asc', 'end_time' => 'asc'])
            ->limit($limit)
            ->select();
    }

    /**
     * 获取拼单详情 (详细)
     * @param int $taskId 拼单ID
     * @return Task|array
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getDetail(int $taskId)
    {
        // 获取拼单详情
        $detail = static::getBasic($taskId);
        // 获取拼单的成员列表
        $TaskUsersModel = new TaskUsersModel;
        $detail['users'] = $TaskUsersModel->getUserList($taskId);
        // 当前用户是否为发起人
        $detail['is_leader'] = $this->getIsLeader($detail);
        // 当前用户是否已参团
        $detail['is_join'] = $this->getIsjoin($detail);
        return $detail;
    }

    /**
     * 当前用户是否为发起人
     * @param $detail
     * @return bool
     * @throws BaseException
     */
    private function getIsLeader($detail): bool
    {
        $userId = UserService::getCurrentLoginUserId(false);
        return !empty($userId) && $userId == $detail['user_id'];
    }

    /**
     * 当前用户是否已参团
     * @param $detail
     * @return bool
     * @throws BaseException
     */
    private function getIsjoin($detail): bool
    {
        $userId = UserService::getCurrentLoginUserId(false);
        return $userId > 0 && TaskUsersModel::isJoin($detail['task_id'], $userId);
    }

    /**
     * 更新拼单信息 (用于订单付款后)
     * @param int $taskId 拼单ID
     * @param int $userId 用户ID
     * @param int $orderId 订单ID
     * @return bool
     * @throws BaseException
     */
    public function updateTaskInfo(int $taskId, int $userId, int $orderId): bool
    {
        // 获取拼单详情
        $model = static::getBasic($taskId);
        // 验证当前拼单是否允许加入新成员
        if (!$this->checkToJoin($model, $userId, false)) {
            return false;
        }
        // 已拼人数
        $model['actual_people'] = $model['actual_people'] + 1;
        $joinedPeople = $model['actual_people'] + $model['robot_people'];
        // 判断拼单状态
        if ($joinedPeople >= $model['people']) {
            $model['complete_time'] = time();
            $model['status'] = TaskStatusEnum::SUCCESS;
        }
        // 创建拼单成员
        $this->createTaskUser($taskId, $userId, $orderId, false, $model['store_id']);
        // 保存拼单信息
        return $model->save();
    }

    /**
     * 新增拼单成员
     * @param int $taskId
     * @param int $userId
     * @param int $orderId
     * @param bool $isLeader
     * @param int $storeId
     * @return void
     */
    private function createTaskUser(int $taskId, int $userId, int $orderId, bool $isLeader, int $storeId): void
    {
        $model = new TaskUsersModel;
        $model->save([
            'task_id' => $taskId,
            'order_id' => $orderId,
            'user_id' => $userId,
            'is_leader' => $isLeader,
            'store_id' => $storeId,
        ]);
    }

    /**
     * 创建新拼单记录
     * @param int $userId 用户ID
     * @param GrouponGoodsModel $goodsInfo 拼团商品信息
     * @param int $stepPeople 阶梯团的人数
     * @return false|int
     */
    public function createTask(int $userId, int $orderId, GrouponGoodsModel $goodsInfo, int $stepPeople)
    {
        // 保存新的拼单记录
        $people = $goodsInfo['active_type'] === ActiveTypeEnum::STEPS ? $stepPeople : $goodsInfo['people'];
        $status = $this->save([
            'groupon_goods_id' => $goodsInfo['groupon_goods_id'],
            'goods_id' => $goodsInfo['goods_id'],
            'active_type' => $goodsInfo['active_type'],
            'people' => $people,
            'actual_people' => 1,
            'user_id' => $userId,
            'start_time' => time(),
            'end_time' => time() + ($goodsInfo['group_time'] * 60 * 60),
            'status' => TaskStatusEnum::NORMAL,
            'store_id' => $goodsInfo['store_id'],
        ]);
        // 创建拼单成员
        $this->createTaskUser((int)$this['task_id'], $userId, $orderId, true, $goodsInfo['store_id']);
        return $status ? (int)$this['task_id'] : false;
    }
}