package com.zhongzheng.modules.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.modules.exam.mapper.ExamApplyMapper;
import com.zhongzheng.modules.exam.vo.ExamApplySiteTimeVo;
import com.zhongzheng.modules.exam.vo.ExamApplySiteVo;
import com.zhongzheng.modules.user.bo.*;
import com.zhongzheng.modules.user.vo.UserSubscribeImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.zhongzheng.modules.user.domain.UserSubscribe;
import com.zhongzheng.modules.user.mapper.UserSubscribeMapper;
import com.zhongzheng.modules.user.vo.UserSubscribeVo;
import com.zhongzheng.modules.user.service.IUserSubscribeService;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户预约考试Service业务层处理
 *
 * @author ruoyi
 * @date 2021-12-07
 */
@Service
public class UserSubscribeServiceImpl extends ServiceImpl<UserSubscribeMapper, UserSubscribe> implements IUserSubscribeService {

    @Autowired
    private ExamApplyMapper examApplyMapper;

    @Override
    public UserSubscribeVo queryById(Long subscribeId) {
        UserSubscribe db = this.baseMapper.selectById(subscribeId);
        return BeanUtil.toBean(db, UserSubscribeVo.class);
    }

    @Override
    public List<UserSubscribeVo> queryList(UserSubscribeQueryBo bo) {
        LambdaQueryWrapper<UserSubscribe> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getGoodsId() != null, UserSubscribe::getGoodsId, bo.getGoodsId());
        lqw.eq(bo.getUserId() != null, UserSubscribe::getUserId, bo.getUserId());
        lqw.eq(bo.getSubscribeStatus() != null, UserSubscribe::getSubscribeStatus, bo.getSubscribeStatus());
        lqw.eq(bo.getBeforeStatus() != null, UserSubscribe::getBeforeStatus, bo.getBeforeStatus());
        lqw.eq(bo.getExamStatus() != null, UserSubscribe::getExamStatus, bo.getExamStatus());
        lqw.eq(bo.getPerformance() != null, UserSubscribe::getPerformance, bo.getPerformance());
        lqw.eq(bo.getResult() != null, UserSubscribe::getResult, bo.getResult());
        lqw.eq(StrUtil.isNotBlank(bo.getCertificateCode()), UserSubscribe::getCertificateCode, bo.getCertificateCode());
        lqw.eq(bo.getApplyId() != null, UserSubscribe::getApplyId, bo.getApplyId());
        lqw.eq(bo.getStudentType() != null, UserSubscribe::getStudentType, bo.getStudentType());
        lqw.eq(bo.getExamExpend() != null, UserSubscribe::getExamExpend, bo.getExamExpend());
        lqw.eq(bo.getBeforeExpend() != null, UserSubscribe::getBeforeExpend, bo.getBeforeExpend());
        return entity2Vo(this.list(lqw));
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<UserSubscribeVo> entity2Vo(Collection<UserSubscribe> collection) {
        List<UserSubscribeVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, UserSubscribeVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<UserSubscribe> page = (Page<UserSubscribe>) collection;
            Page<UserSubscribeVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Long insertByAddBo(UserSubscribeAddBo bo) {
        UserSubscribe add = BeanUtil.toBean(bo, UserSubscribe.class);
        validEntityBeforeSave(add);
        add.setSubscribeStatus(1);
        add.setExamStatus(0);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        this.save(add);
        return add.getSubscribeId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(UserSubscribeEditBo bo) {
        for (Long subscribe : bo.getSubscribeId()) {
            UserSubscribe update = new UserSubscribe();
            update.setSubscribeId(subscribe);
            update.setSubscribeStatus(bo.getSubscribeStatus());
            update.setExamStatus(bo.getExamStatus());
            update.setRemark(bo.getRemark());
            update.setBeforeId(bo.getBeforeId());
            update.setBeforeStatus(bo.getBeforeStatus());
            update.setUpdateTime(DateUtils.getNowTime());
            boolean b = this.updateById(update);
        }
        return true;
    }

    @Override
    public Boolean updateByEditSingleBo(UserAppSubscribeEditBo bo) {
        UserSubscribe update = BeanUtil.toBean(bo, UserSubscribe.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(UserSubscribe entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public List<UserSubscribeVo> listSubscribe(UserSubscribeQueryBo bo) {
        List<UserSubscribeVo> userSubscribeVos = baseMapper.listSubscribe(bo);
        return userSubscribeVos;
    }

    @Override
    public boolean editCertificate(List<UserSubscribeCertificateEditBo> bo) {
        for (UserSubscribeCertificateEditBo userSubscribeCertificateEditBo : bo) {
            UserSubscribe update = new UserSubscribe();
            update.setSubscribeId(userSubscribeCertificateEditBo.getSubscribeId());
            update.setPerformance(userSubscribeCertificateEditBo.getPerformance());
            update.setResult(userSubscribeCertificateEditBo.getResult());
            update.setCertificateCode(userSubscribeCertificateEditBo.getCertificateCode());
            update.setRemark(userSubscribeCertificateEditBo.getRemark());
            update.setUpdateTime(DateUtils.getNowTime());
            boolean b = this.updateById(update);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<UserSubscribeImport> importData(List<UserSubscribeImport> userSubscribeImportList) {
        if (CollectionUtils.isEmpty(userSubscribeImportList)) {
            throw new IllegalArgumentException("请勿导入空表格");
        }
        List<UserSubscribeImport> userSubscribeImports = new ArrayList<>();
        for (UserSubscribeImport userSubscribeImport : userSubscribeImportList) {
            UserSubscribeAddBo userSubscribeAddBo = new UserSubscribeAddBo();
            //查询商品
            if (StringUtils.isEmpty(userSubscribeImport.getCode())) {
                userSubscribeImport.setCause("未填商品编码");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long goodsId = baseMapper.selectGoodsId(userSubscribeImport.getCode());
            if (goodsId == null) {
                userSubscribeImport.setCause("商品编码错误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSubscribeAddBo.setGoodsId(goodsId);
            //查询学员Id
            if (StringUtils.isEmpty(userSubscribeImport.getUserName()) || userSubscribeImport.getIdCard() == null) {
                userSubscribeImport.setCause("学员信息未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long userId = baseMapper.selectUserId(userSubscribeImport.getUserName(), userSubscribeImport.getIdCard());
            if (userId == null) {
                userSubscribeImport.setCause("用户信息错误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSubscribeAddBo.setUserId(userId);

            if (StringUtils.isEmpty(userSubscribeImport.getSubscribeStatus())) {
                userSubscribeImport.setCause("预约状态为空");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            if (userSubscribeImport.getSubscribeStatus().equals("正常")) {
                userSubscribeAddBo.setSubscribeStatus(1);
            }
            if (userSubscribeImport.getSubscribeStatus().equals("取消")) {
                userSubscribeAddBo.setSubscribeStatus(0);
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getBeforeStatus()) && !StringUtils.isEmpty(userSubscribeImport.getBeforeName())) {
                Long beforeId = baseMapper.selectBeforeId(userSubscribeImport.getBeforeName());
                if (beforeId == null) {
                    userSubscribeImport.setCause("前培标题有误");
                    userSubscribeImports.add(userSubscribeImport);
                    continue;
                }
                userSubscribeAddBo.setBeforeStatus(1);
                userSubscribeAddBo.setBeforeId(beforeId);
                userSubscribeAddBo.setBeforeExpend(1);
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getExamStatus())) {
                if (userSubscribeImport.getExamStatus().equals("待登记")) {
                    userSubscribeAddBo.setExamStatus(0);
                } else if (userSubscribeImport.getExamStatus().equals("正常")) {
                    userSubscribeAddBo.setExamStatus(1);
                } else if (userSubscribeImport.getExamStatus().equals("缺考")) {
                    userSubscribeAddBo.setExamStatus(2);
                } else if (userSubscribeImport.getExamStatus().equals("作弊")) {
                    userSubscribeAddBo.setExamStatus(3);
                } else if (userSubscribeImport.getExamStatus().equals("替考")) {
                    userSubscribeAddBo.setExamStatus(4);
                }
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getResult())) {
                if (userSubscribeImport.getResult().equals("不通过")) {
                    userSubscribeAddBo.setResult(0);
                } else if (userSubscribeImport.getResult().equals("通过")) {
                    userSubscribeAddBo.setResult(1);
                }
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getCertificateCode())) {
                userSubscribeAddBo.setCertificateCode(userSubscribeImport.getCertificateCode());
            }
            if (StringUtils.isEmpty(userSubscribeImport.getApplyName())) {
                userSubscribeImport.setCause("考试标题有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long applyId = baseMapper.selectApplyId(userSubscribeImport.getApplyName());
            if (applyId == null) {
                userSubscribeImport.setCause("考试标题有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSubscribeAddBo.setApplyId(applyId);

            Long subscribeId = baseMapper.selectSubscribeId(applyId, goodsId, userId);
            if (subscribeId != null) {
                userSubscribeImport.setCause("该学员在考试计划中有预约考试数据，请确认该学员预约考试状况");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getStudentTypeName())) {
                if (userSubscribeImport.getStudentTypeName().equals("非补考学员")) {
                    userSubscribeAddBo.setStudentType(1);
                } else {
                    userSubscribeAddBo.setStudentType(2);
                }
            } else {
                userSubscribeImport.setCause("学员报名类型有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteAddress())) {
                userSubscribeAddBo.setApplySiteAddress(userSubscribeImport.getApplySiteAddress());
            } else {
                userSubscribeImport.setCause("地址未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (userSubscribeImport.getApplySiteExamTime() != null) {
                userSubscribeAddBo.setApplySiteExamTime(Convert.toLong(userSubscribeImport.getApplySiteExamTime().getDay()));
            } else {
                userSubscribeImport.setCause("考试时间未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteTime())) {
                String[] split = userSubscribeImport.getApplySiteTime().split("-");
                if (split.length < 2) {
                    userSubscribeImport.setCause("考试时间段错误");
                    userSubscribeImports.add(userSubscribeImport);
                    continue;
                }
                String startTime = split[0];
                String endTime = split[1];
                startTime = startTime.replace(":", "-");
                endTime = endTime.replace(":", "-");

                userSubscribeAddBo.setApplySiteStartTime(startTime);
                userSubscribeAddBo.setApplySiteEndTime(endTime);
            } else {
                userSubscribeImport.setCause("考试时间段未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }


            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteAddressTrain())) {
                userSubscribeAddBo.setApplySiteAddressTrain(userSubscribeImport.getApplySiteAddressTrain());
            }

            if (userSubscribeImport.getApplySiteExamTrainTime() != null) {
                userSubscribeAddBo.setApplySiteExamTrainTime(Convert.toLong(userSubscribeImport.getApplySiteExamTrainTime().getDay()));
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteTrainTime())) {
                String[] split = userSubscribeImport.getApplySiteTrainTime().split("-");
                if (split.length < 2) {
                    userSubscribeImport.setCause("考试时间段错误");
                    userSubscribeImports.add(userSubscribeImport);
                    continue;
                }
                String startTime = split[0];
                String endTime = split[1];
                startTime = startTime.replace(":", "-");
                endTime = endTime.replace(":", "-");

                userSubscribeAddBo.setApplySiteStartTrainTime(startTime);
                userSubscribeAddBo.setApplySiteEndTrainTime(endTime);
            }

            userSubscribeAddBo.setCreateTime(DateUtils.getNowTime());
            userSubscribeAddBo.setUpdateTime(DateUtils.getNowTime());
            this.insertByAddBo(userSubscribeAddBo);
        }
        return userSubscribeImports;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<UserSubscribeImport> importUpdateData(List<UserSubscribeImport> userSubscribeImportList) {
        if (CollectionUtils.isEmpty(userSubscribeImportList)) {
            throw new IllegalArgumentException("请勿导入空表格");
        }
        List<UserSubscribeImport> userSubscribeImports = new ArrayList<>();
        for (UserSubscribeImport userSubscribeImport : userSubscribeImportList) {
            UserSubscribe userSbusciEditBo = new UserSubscribe();
            //查询商品
            if (StringUtils.isEmpty(userSubscribeImport.getCode())) {
                userSubscribeImport.setCause("未填商品编码");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long goodsId = baseMapper.selectGoodsId(userSubscribeImport.getCode());
            if (goodsId == null) {
                userSubscribeImport.setCause("商品编码错误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSbusciEditBo.setGoodsId(goodsId);
            //查询学员Id
            if (StringUtils.isEmpty(userSubscribeImport.getUserName()) || userSubscribeImport.getIdCard() == null) {
                userSubscribeImport.setCause("学员信息未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long userId = baseMapper.selectUserId(userSubscribeImport.getUserName(), userSubscribeImport.getIdCard());
            if (userId == null) {
                userSubscribeImport.setCause("用户信息错误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSbusciEditBo.setUserId(userId);

            if (StringUtils.isEmpty(userSubscribeImport.getSubscribeStatus())) {
                userSubscribeImport.setCause("预约状态为空");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            if (userSubscribeImport.getSubscribeStatus().equals("正常")) {
                userSbusciEditBo.setSubscribeStatus(1);
            }
            if (userSubscribeImport.getSubscribeStatus().equals("取消")) {
                userSbusciEditBo.setSubscribeStatus(0);
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getBeforeStatus())) {
                if (userSubscribeImport.getBeforeStatus().equals("是")) {
                    if (StringUtils.isEmpty(userSubscribeImport.getBeforeName())) {
                        userSubscribeImport.setCause("前培标题有误");
                        userSubscribeImports.add(userSubscribeImport);
                        continue;
                    }
                    Long beforeId = baseMapper.selectBeforeId(userSubscribeImport.getBeforeName());
                    if (beforeId == null) {
                        userSubscribeImport.setCause("前培标题有误");
                        userSubscribeImports.add(userSubscribeImport);
                        continue;
                    }
                    userSbusciEditBo.setBeforeStatus(1);
                    userSbusciEditBo.setBeforeId(beforeId);
                    userSbusciEditBo.setBeforeExpend(1);
                } else if (userSubscribeImport.getBeforeStatus().equals("否")) {
                    userSbusciEditBo.setBeforeStatus(0);
                }
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getExamStatus())) {
                if (userSubscribeImport.getExamStatus().equals("待登记")) {
                    userSbusciEditBo.setExamStatus(0);
                } else if (userSubscribeImport.getExamStatus().equals("正常")) {
                    userSbusciEditBo.setExamStatus(1);
                } else if (userSubscribeImport.getExamStatus().equals("缺考")) {
                    userSbusciEditBo.setExamStatus(2);
                } else if (userSubscribeImport.getExamStatus().equals("作弊")) {
                    userSbusciEditBo.setExamStatus(3);
                } else if (userSubscribeImport.getExamStatus().equals("替考")) {
                    userSbusciEditBo.setExamStatus(4);
                }
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getResult())) {
                if (userSubscribeImport.getResult().equals("不通过")) {
                    userSbusciEditBo.setResult(0);
                } else if (userSubscribeImport.getResult().equals("通过")) {
                    userSbusciEditBo.setResult(1);
                }
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getCertificateCode())) {
                userSbusciEditBo.setCertificateCode(userSubscribeImport.getCertificateCode());
            }

            if (StringUtils.isEmpty(userSubscribeImport.getApplyName())) {
                userSubscribeImport.setCause("考试标题有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            Long applyId = baseMapper.selectApplyId(userSubscribeImport.getApplyName());
            if (applyId == null) {
                userSubscribeImport.setCause("考试标题有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSbusciEditBo.setApplyId(applyId);
            Long subscribeId = baseMapper.selectSubscribeId(applyId, goodsId, userId);
            if (subscribeId == null) {
                userSubscribeImport.setCause("该学员在考试计划中无预约数据，请确认该学员已预约考试");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }
            userSbusciEditBo.setSubscribeId(subscribeId);

            if (!StringUtils.isEmpty(userSubscribeImport.getStudentTypeName())) {
                if (userSubscribeImport.getStudentTypeName().equals("非补考学员")) {
                    userSbusciEditBo.setStudentType(1);
                } else {
                    userSbusciEditBo.setStudentType(2);
                }
            } else {
                userSubscribeImport.setCause("学员报名类型有误");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteAddress())) {
                userSbusciEditBo.setApplySiteAddress(userSubscribeImport.getApplySiteAddress());
            } else {
                userSubscribeImport.setCause("地址未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (userSubscribeImport.getApplySiteExamTime() != null) {
                userSbusciEditBo.setApplySiteExamTime(Convert.toLong(userSubscribeImport.getApplySiteExamTime().getDay()));
            } else {
                userSubscribeImport.setCause("考试时间未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteTime())) {
                String[] split = userSubscribeImport.getApplySiteTime().split("-");
                if (split.length < 2) {
                    userSubscribeImport.setCause("考试时间段错误");
                    userSubscribeImports.add(userSubscribeImport);
                    continue;
                }
                String startTime = split[0];
                String endTime = split[1];
                startTime = startTime.replace(":", "-");
                endTime = endTime.replace(":", "-");

                userSbusciEditBo.setApplySiteStartTime(startTime);
                userSbusciEditBo.setApplySiteEndTime(endTime);
            } else {
                userSubscribeImport.setCause("考试时间段未填");
                userSubscribeImports.add(userSubscribeImport);
                continue;
            }


            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteAddressTrain())) {
                userSbusciEditBo.setApplySiteAddressTrain(userSubscribeImport.getApplySiteAddressTrain());
            }

            if (userSubscribeImport.getApplySiteExamTrainTime() != null) {
                userSbusciEditBo.setApplySiteExamTrainTime(Convert.toLong(userSubscribeImport.getApplySiteExamTrainTime().getDay()));
            }

            if (!StringUtils.isEmpty(userSubscribeImport.getApplySiteTrainTime())) {
                String[] split = userSubscribeImport.getApplySiteTrainTime().split("-");
                if (split.length < 2) {
                    userSubscribeImport.setCause("考试时间段错误");
                    userSubscribeImports.add(userSubscribeImport);
                    continue;
                }
                String startTime = split[0];
                String endTime = split[1];
                startTime = startTime.replace(":", "-");
                endTime = endTime.replace(":", "-");

                userSbusciEditBo.setApplySiteStartTrainTime(startTime);
                userSbusciEditBo.setApplySiteEndTrainTime(endTime);
            }

            userSbusciEditBo.setUpdateTime(DateUtils.getNowTime());
            this.updateById(userSbusciEditBo);
        }
        return userSubscribeImports;
    }
}
