package com.ym.mec.biz.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.TempLittleArtistTrainingCampUserRelationDao;
import com.ym.mec.biz.dal.entity.SysConfig;
import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCampUserRelation;
import com.ym.mec.biz.dal.vo.TempCampUserQualificationsVo;
import com.ym.mec.biz.service.SysConfigService;
import com.ym.mec.biz.service.TempLittleArtistTrainingCampService;
import com.ym.mec.biz.service.TempLittleArtistTrainingCampUserRelationService;
import com.ym.mec.common.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * 训练营与学生关系表(TempLittleArtistTrainingCampUserRelation)表服务实现类
 *
 * @author hgw
 * @since 2022-05-18 15:48:00
 */
@Service("tempLittleArtistTrainingCampUserRelationService")
public class TempLittleArtistTrainingCampUserRelationServiceImpl extends ServiceImpl<TempLittleArtistTrainingCampUserRelationDao, TempLittleArtistTrainingCampUserRelation> implements TempLittleArtistTrainingCampUserRelationService {

    private final static Logger log = LoggerFactory.getLogger(TempLittleArtistTrainingCampUserRelationServiceImpl.class);
    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private TempLittleArtistTrainingCampService tempLittleArtistTrainingCampService;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public TempLittleArtistTrainingCampUserRelationDao getDao() {
        return this.baseMapper;
    }

    /**
     * 参与训练营
     *
     * @param campId 训练营id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(Integer campId) {
        SysUser user = getUser();
        RBucket<Object> addCamp = redissonClient.getBucket("TEMP:CAMP_ADD:" + user.getId());
        if (!addCamp.trySet(1, 10, TimeUnit.SECONDS)) {
            throw new BizException("正在登记训练营，请勿重复提交");
        }
        TempLittleArtistTrainingCampUserRelation one = this.getOne(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaQuery()
                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId())
                .isNotNull(TempLittleArtistTrainingCampUserRelation::getActivityId));
        if (Objects.nonNull(one)) {
            throw new BizException("您已登记训练营!");
        }
        int count = this.count(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaUpdate()
                .eq(TempLittleArtistTrainingCampUserRelation::getActivityId, campId));
        int maxNum = 2000;
        if (count >= maxNum) {
            throw new BizException("人数已报满！");
        }
        //修改训练营人数，小于2000人
        int updateFlag = tempLittleArtistTrainingCampService.getDao().updateUserNum(campId, maxNum);
        if (updateFlag == 0) {
            throw new BizException("人数已报满！");
        }
        this.update(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaUpdate()
                .set(TempLittleArtistTrainingCampUserRelation::getActivityId, campId)
                .set(TempLittleArtistTrainingCampUserRelation::getState, TempLittleArtistTrainingCampUserRelation.APPLY)
                .set(TempLittleArtistTrainingCampUserRelation::getApplyTime, new Date())
                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId()));
        addCamp.delete();
    }

    /**
     * 查询当前登录学生有没有资格参加训练营
     */
    @Override
    public TempCampUserQualificationsVo checkCampQualifications() {
        TempCampUserQualificationsVo vo = new TempCampUserQualificationsVo();
        vo.setQualifications(1);//训练营资格 有资格0  无资格1
        SysUser user = getUser();
        if (!user.getUserType().contains("STUDENT")) {
            return vo;
        }
        TempLittleArtistTrainingCampUserRelation relation = this.getOne(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaQuery()
                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId()));
        //该学员未购买
        if (Objects.isNull(relation)) {
            return vo;
        }
        //已报名
        if (relation.getState().equals(TempLittleArtistTrainingCampUserRelation.APPLY)) {
            return vo;
        }

        //小小训训练营文案及标题-默认
        vo.setContent("小小艺术家好习惯养成训练营邀请函");
        vo.setCampTitle("恭喜你获得小小艺术家好习惯养成训练营体验资格，请及时通过训练营登记界面选择您要参加的训练营周期，不要浪费资格哦！");
        //取配置中的文案及标题
        this.setValue("temp_little_artist_training_camp_content", vo::setContent);
        this.setValue("temp_little_artist_training_camp_title", vo::setCampTitle);
        this.setValue("temp_little_artist_training_camp_url", vo::setUrl);
        this.setValue(SysConfigService.BASE_API_URL, (a) -> vo.setUrl(a + vo.getUrl()));

        vo.setCampId(relation.getActivityId());
        vo.setUserName(user.getUsername());
        vo.setQualifications(0);//训练营资格 有资格0  无资格1
        return vo;
    }

    private void setValue(String key, Consumer<String> consumer) {
        Optional.of(key)
                .map(sysConfigService::findByParamName)
                .filter(s -> StringUtils.isNotBlank(s.getParanValue()))
                .ifPresent(sysConfig -> consumer.accept(sysConfig.getParanValue()));
    }

    private SysUser getUser() {
        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
    }

}

