<?php

namespace app\traits\order;

use app\exception\RepositoryException;
use app\model\Account;
use app\model\Order;
use app\model\OrderActivity;
use app\model\OrderGroupList;
use app\model\Sku;
use app\model\Spu;
use app\model\SpuActivity;
use Exception;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\Model;

/**
 * 活动商品相关
 *
 * Trait ShoppingCartTrait
 * @package app\traits\order
 */
trait ActivityTrait
{
    /**
     * 创建活动商品订单
     * 每个活动商品均要创建一个活动订单
     *
     * @param  int  $accountId
     * @param  string  $orderCoding  订单编号
     * @param  array  $skuList  sku列表
     * @throws Exception
     */
    public function createActivityOrder(int $accountId, string $orderCoding, array $skuList)
    {
        $activityList    = [];//活动商品订单列表
        $activitySkuList = [];//活动商品SKU列表
        $groupList       = [];//拼团列表
        $groupIds        = [];//拼团ID列表

        $now = date('Y-m-d H:i:s');
        $this->checkActivity($skuList);
        foreach ($skuList as $sku) {
            $spuActivityId = $sku['spu_activity_id'];

            if ($sku['is_activity'] == Spu::COMMON_OFF) {
                continue;
            }
            if (!isset($activitySkuList[$spuActivityId])) {
                $activitySkuList[$spuActivityId] = [];
            }

            if (!isset($activityList[$spuActivityId])) {
                $activityList[$spuActivityId]                    = [];
                $activityList[$spuActivityId]['account_id']      = $accountId;
                $activityList[$spuActivityId]['num']             = 0;
                $activityList[$spuActivityId]['total_price']     = 0;
                $activityList[$spuActivityId]['coding']          = $orderCoding;
                $activityList[$spuActivityId]['spu_name']        = $sku['goods_name'];
                $activityList[$spuActivityId]['type']            = $sku['activity_type'];
                $activityList[$spuActivityId]['created_at']      = $now;
                $activityList[$spuActivityId]['updated_at']      = $now;
                $activityList[$spuActivityId]['spu_activity_id'] = $spuActivityId;
            }

            $activityList[$spuActivityId]['num']         += $sku['num'];
            $activityList[$spuActivityId]['total_price'] += $sku['price'] * $sku['num'];

            $activitySkuList[$spuActivityId][] = $sku;
        }

        foreach ($activityList as &$activity) {
            $activity['sku_info'] = json_encode($activitySkuList[$activity['spu_activity_id']], JSON_UNESCAPED_UNICODE);
        }
    }

    /**
     * 创建虚拟拼团
     *
     * @param  int  $activityId  商品ID
     * @param  int  $num  虚拟拼团数量 默认1
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function createVirtualGroupList(int $activityId, int $num = 1): bool
    {
        $groupList = [];
        $activity  = SpuActivity::findById($activityId);
        if ($activity['activity_type'] != Spu::TYPE_GROUP_MAKE) {
            return false;
        }
        $sku    = Sku::findOne(['spu_activity_id' => $activityId]);
        $covers = Account::whereNotNull('headimgurl')->limit($num)->column('headimgurl');
        $names  = [
            '13****', '15****', '18****', '17****', '19****'
        ];
        for ($i = 0; $i < $num; $i++) {
            $groupArr = [];
            // 拼团列表
            $groupArr['account_id']      = 0;
            $groupArr['spu_activity_id'] = $activityId;
            $groupArr['num']             = 0;
            $groupArr['price']           = 0;
            $groupArr['total_price']     = 0;
            $groupArr['group_num']       = $activity['group_num'];
            $groupArr['surplus']         = $activity['group_num'] - 1;
            $groupArr['sku_coding']      = $sku['coding'];
            $groupArr['group_id']        = 0;
            $groupArr['coding']          = '';
            $groupTime                   = $activity['group_time'] * 60;//拼团有效期(转为分钟)
            $groupTime                   = $groupTime ?: rand(11, 23) * 60;//默认11~23小时随机
            $groupArr['created_at']      = date('Y-m-d H:i:s');
            $groupArr['expired_at']      = date('Y-m-d H:i:s', strtotime('+'.$groupTime.' minutes'));
            $groupArr['is_initiator']    = 1;//是否发起人
            $groupArr['is_virtual']      = 1;//是否虚拟拼团
            shuffle($names);
            shuffle($covers);
            $groupArr['virtual_name']  = $names[0] ?? '13****';//虚拟用户名称
            $groupArr['virtual_cover'] = $covers[0] ?? '';//虚拟用户头像
            if (!empty($groupArr)) {
                $groupList[] = $groupArr;
            }
        }

        if (!empty($groupList)) {
            OrderGroupList::createGroup($groupList);//创建拼团
        }

        return true;
    }

    /**
     * @param  string  $activityCoding
     * @return bool
     */
    public function setPaid(string $activityCoding)
    {
        return true;
    }

    public function checkActivity(array $skuList)
    {
        //检测拼团名额是否已满 等
    }

    /**
     * 获取拼团列表
     *
     * @param  int  $spuActivityId
     * @return OrderGroupList[]|array|Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws RepositoryException
     */
    public function getGroupList(int $spuActivityId)
    {
        if (!$activity = SpuActivity::findById($spuActivityId, ['id', 'cover', 'group_num', 'saleable'])) {
            throw new RepositoryException('活动商品不存在或已下架');
        }

        if ($activity['saleable'] == SpuActivity::COMMON_OFF) {
            throw new RepositoryException('活动商品已下架');
        }

        $groupList = OrderGroupList::where('spu_activity_id', $spuActivityId)
            ->where('expired_at', '>', date('Y-m-d H:i:s'))
            ->where('group_id', '>', 0)
            ->whereNull('deleted_at')
            ->group('group_id')
            ->field('count(`id`) as count, group_id')
            ->select();
        $groupIds  = $groupList->where('count', '<=', $activity['group_num'] - 1)->column('group_id');
        $groupNum  = $groupList->where('count', '<=', $activity['group_num'] - 1)->column('count', 'group_id');
        $list      = OrderGroupList::with(['accountCover'])
            ->where('id', 'in', $groupIds)
            ->whereNull('deleted_at')
            ->where('expired_at', '>', date('Y-m-d H:i:s'))
            ->where('is_initiator', OrderGroupList::COMMON_ON)
            ->order('expired_at', 'asc')
            ->field('id,is_virtual,spu_activity_id,num,account_id,expired_at as time,group_id,virtual_name,virtual_cover')
            ->select();

        return $list->each(function ($item) use ($activity, $groupNum) {
            // 剩余数量=团购最大数 - 拼团人数
            $surplus   = $activity['group_num'] - $groupNum[$item->id];
            $item->num = $surplus;
            if ($item->is_virtual == 1) {
                $item->name  = $item->virtual_name;
                $item->cover = $item->virtual_cover;
            }
            unset($item->account_id);
            unset($item->spu_activity_id);
            unset($item->group_id);
            unset($item->is_virtual);
            unset($item->virtual_name);
            unset($item->virtual_cover);
            if ($surplus <= 0) {
                unset($item);
            }
        });
    }
}