package com.qs.mp.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.qs.mp.admin.domain.*;
import com.qs.mp.admin.domain.param.CdKeyCreateParam;
import com.qs.mp.admin.domain.vo.CdKeyGroupVO;
import com.qs.mp.admin.mapper.CdKeyGroupMapper;
import com.qs.mp.admin.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.common.constant.Constants;
import com.qs.mp.common.enums.*;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.framework.service.IAsyncTaskService;
import com.qs.mp.system.service.id.BizIdGenerator;
import ma.glasnost.orika.MapperFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther quanshu
 * @create 2023-05-16 17:19:30
 * @describe 兑换码组服务实现类
 */
@Service
public class CdKeyGroupServiceImpl extends ServiceImpl<CdKeyGroupMapper, CdKeyGroup> implements ICdKeyGroupService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private BizIdGenerator bizIdGenerator;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private ICouponService couponService;

    @Autowired
    private ICouponPkgService couponPkgService;

    @Autowired
    private ICdKeyGroupGoodsService cdKeyGroupGoodsService;

    @Autowired
    private ICdKeyService cdKeyService;

    @Autowired
    private IAsyncTaskService asyncTaskService;

    @Autowired
    private IChannelService channelService;


    @Override
    public List<CdKeyGroupVO> listCdKeyGroupListVO(QueryWrapper<CdKeyGroup> queryWrapper) {
        return getBaseMapper().listCdKeyGroupListVO(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createCdKeyGroup(CdKeyCreateParam param) {

        Integer totalQuantity = param.getQuantity();
        Integer goodsQuantity = 0;
        for (CdKeyGroupGoods cdKeyGroupGoods : param.getGoodsList()) {
            goodsQuantity += cdKeyGroupGoods.getQuantity();
        }
        if (!totalQuantity.equals(goodsQuantity)) {
            throw new ServiceException("兑换码数量不一致");
        }

        Channel channel = channelService.getById(param.getChannelId());
        if (channel == null) {
            LogUtil.error(logger,"门店不存在,channelId:{0}", param.getChannelId());
            throw new ServiceException("门店不存在");
        }
        // 生成兑换码组
        CdKeyGroup cdKeyGroup = mapperFacade.map(param, CdKeyGroup.class);
        cdKeyGroup.setGroupId(bizIdGenerator.newId());
        cdKeyGroup.setTitle(param.getTitle());
        cdKeyGroup.setStatus(CdKeyGroupStatusEnum.WAITING);
        cdKeyGroup.setSiteName(channel.getName());
        cdKeyGroup.setCreatedTime(new Date());
        cdKeyGroup.setUpdatedTime(new Date());
        this.save(cdKeyGroup);


        // 关联商品
        if (CollectionUtils.isNotEmpty(param.getGoodsList())) {
            List<CdKeyGroupGoods> cdKeyGroupGoodsList = new ArrayList<>();
            // 设置groupId和商品信息
            for (CdKeyGroupGoods cdKeyGroupGoods : param.getGoodsList()) {
                CdKeyGroupGoods groupGoods = new CdKeyGroupGoods();
                BeanUtils.copyProperties(cdKeyGroupGoods, groupGoods);
                groupGoods.setGroupId(cdKeyGroup.getGroupId());
                if (CdKeyGroupGoodsTypeEnum.COUPON.equals(cdKeyGroupGoods.getType())) {
                    Coupon coupon = couponService.getById(groupGoods.getRefId());
                    if (coupon == null) {
                        LogUtil.error(logger,"关联优惠券信息不存在,groupId:{0}", cdKeyGroup.getGroupId());
                        throw new ServiceException("关联优惠券信息不存在");
                    }
                    groupGoods.setTitle(coupon.getTitle());
                    groupGoods.setPicUrl(coupon.getPicUrl());
                    groupGoods.setValue(coupon.getDiscount());
                    groupGoods.setQuantity(cdKeyGroupGoods.getQuantity());
                } else if (CdKeyGroupGoodsTypeEnum.COUPON_PKG.equals(cdKeyGroupGoods.getType())) {
                    CouponPkg couponPkg = couponPkgService.getById(groupGoods.getRefId());
                    if (couponPkg == null) {
                        LogUtil.error(logger,"关联券包信息不存在,groupId:{0}", cdKeyGroup.getGroupId());
                        throw new ServiceException("关联券包信息不存在");
                    }
                    groupGoods.setTitle(couponPkg.getTitle());
                    groupGoods.setPicUrl(couponPkg.getPicUrl());
                    groupGoods.setValue(couponPkg.getFacePrice());
                    groupGoods.setQuantity(cdKeyGroupGoods.getQuantity());
                } else if (CdKeyGroupGoodsTypeEnum.GOODS.equals(cdKeyGroupGoods.getType())) {
                    Goods goods = goodsService.getById(cdKeyGroupGoods.getRefId());
                    if (goods == null) {
                        LogUtil.error(logger, "关联商品信息不存在,groupId:{0}", cdKeyGroup.getGroupId());
                        throw new ServiceException("关联商品信息不存在");
                    }
                    groupGoods.setTitle(goods.getTitle());
                    groupGoods.setPicUrl(goods.getPicUrl());
                    groupGoods.setValue(goods.getValue());
                    groupGoods.setQuantity(cdKeyGroupGoods.getQuantity());
                } else {
                    groupGoods.setTitle("盲豆");
                    groupGoods.setPicUrl(Constants.MANGDOU_PIC);
                    groupGoods.setQuantity(cdKeyGroupGoods.getQuantity());
                }
                cdKeyGroupGoodsList.add(groupGoods);
            }
            if (CollectionUtils.isNotEmpty(cdKeyGroupGoodsList)) {
                cdKeyGroupGoodsService.saveBatch(cdKeyGroupGoodsList);
            }
        }

        if (StringUtils.isNotBlank(cdKeyGroup.getGroupId())) {
            // 插入兑换码生成异步任务
            Assert.isTrue(asyncTaskService.insertAsyncTask(AsyncTaskTypeEnum.CD_KET_GENERATE, cdKeyGroup.getGroupId())
                    , "兑换码组保存，创建异步任务失败.groupId:" + cdKeyGroup.getGroupId());
        }
        return cdKeyGroup.getGroupId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateCdKey(String groupId) {
        QueryWrapper<CdKeyGroupGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id", groupId);
        List<CdKeyGroupGoods> list = cdKeyGroupGoodsService.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            for (CdKeyGroupGoods cdKeyGroupGoods : list) {
                List<CdKey> cdKeyList = new ArrayList<>();
                for (int i = 0; i < cdKeyGroupGoods.getQuantity(); i++) {
                    // 为每一个商品生成兑换码
                    CdKey cdKey = new CdKey();
                    cdKey.setGroupId(groupId);
                    cdKey.setRefId(cdKeyGroupGoods.getRefId());
                    cdKey.setType(cdKeyGroupGoods.getType());
                    cdKey.setGoodsName(cdKeyGroupGoods.getTitle());
                    cdKey.setValue(cdKeyGroupGoods.getValue());
                    cdKey.setPicUrl(cdKeyGroupGoods.getPicUrl());
                    cdKey.setStatus(CdKeyStatusEnum.UNCASHED.getValue());
                    cdKey.setCdKey(cdKeyGenerate());
                    cdKey.setCreateTime(new Date());
                    cdKeyList.add(cdKey);
                }
                cdKeyService.saveBatch(cdKeyList);
            }
        }

        boolean rst = update(new LambdaUpdateWrapper<CdKeyGroup>()
                .set(CdKeyGroup::getStatus, CdKeyGroupStatusEnum.NO_ACTIVE.getValue())
                .eq(CdKeyGroup::getGroupId, groupId));

        Assert.isTrue(rst, "兑换码生成完，兑换码组更新失败,groupId:{0}" + groupId);

    }

    private String cdKeyGenerate() {
        // 生成16位大写字母和数字的随机卡密码的逻辑
        // 可以使用随机数生成器或者其他方式实现
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder codeBuilder = new StringBuilder();
        for (int i = 0; i < 16; i++) {
            int randomIndex = (int) (Math.random() * characters.length());
            codeBuilder.append(characters.charAt(randomIndex));
        }
        return codeBuilder.toString();
    }


}
