package org.dromara.payment.task.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.enums.BusRole;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.payment.common.domain.BusOperLog;
import org.dromara.payment.common.mapper.BusOperLogMapper;
import org.dromara.payment.task.domain.MerTask;
import org.dromara.payment.task.domain.bo.MerTaskBo;
import org.dromara.payment.task.domain.vo.MerTaskVo;
import org.dromara.payment.task.mapper.MerTaskMapper;
import org.dromara.payment.worker.domain.UserWorkerBusiness;
import org.dromara.payment.worker.domain.vo.UserWorkerBusinessVo;
import org.dromara.payment.worker.mapper.UserWorkerBusinessMapper;
import org.springframework.stereotype.Service;
import org.dromara.payment.task.domain.bo.MerTaskEnrollBo;
import org.dromara.payment.task.domain.vo.MerTaskEnrollVo;
import org.dromara.payment.task.domain.MerTaskEnroll;
import org.dromara.payment.task.mapper.MerTaskEnrollMapper;
import org.dromara.payment.task.service.IMerTaskEnrollService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务的报名Service业务层处理
 *
 * @author LionLi
 * @date 2024-04-08
 */
@RequiredArgsConstructor
@Service
public class MerTaskEnrollServiceImpl implements IMerTaskEnrollService {

    @Resource
    private final MerTaskEnrollMapper baseMapper;

    @Resource
    private final MerTaskMapper merTaskMapper;

    @Resource
    private final BusOperLogMapper busOperLogMapper;

    @Resource
    private final UserWorkerBusinessMapper userWorkerBusinessMapper;

    /**
     * 查询任务的报名
     */
    @Override
    public MerTaskEnrollVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询任务的报名列表
     */
    @Override
    public TableDataInfo<MerTaskEnrollVo> queryPageList(MerTaskEnrollBo bo, PageQuery pageQuery) {
        if(null == bo.getTaskId()){
            throw new IllegalArgumentException("项目ID不能为空");
        }

        QueryWrapper<MerTaskEnroll> lqw = buildQueryWrapper2(bo);

        Page<MerTaskEnrollVo> result = baseMapper.selectPageList(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    /**
     * 查询任务的报名列表
     */
    @Override
    public TableDataInfo<MerTaskEnrollVo> queryPageSuccessList(MerTaskEnrollBo bo, PageQuery pageQuery) {
        if(null == bo.getTaskId()){
            throw new IllegalArgumentException("项目ID不能为空");
        }

        bo.setVerifyStatus(Long.valueOf(3));
        QueryWrapper<MerTaskEnroll> lqw = buildQueryWrapper2(bo);

        Page<MerTaskEnrollVo> result = baseMapper.selectPageList(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    @Override
    @Transactional
    public Boolean checkEnrollByBo(MerTaskEnrollBo bo) {
        MerTaskEnroll update = MapstructUtils.convert(bo, MerTaskEnroll.class);
        if(null == bo.getTaskId()){
            throw new IllegalArgumentException("项目ID不能为空");
        }
        if(null == bo.getIds() || bo.getIds().length == 0){
            throw new IllegalArgumentException("子项目ID不能为空");
        }
        Integer busRole = LoginHelper.getBusRole();
        if(busRole != BusRole.SERVICE.getId()
            && busRole != BusRole.MERCHANT.getId() ){
            throw new IllegalArgumentException("当前用户没有审核项目权限，请联系管理员");
        }
        bo.setVerifyBy(LoginHelper.getUsername());
        baseMapper.updateTaskEnrollCheckStatusFailed(bo);
        MerTask task = new MerTask();
        task.setId(bo.getTaskId());
        task.setTaskStatus(7);
        merTaskMapper.updateById(task);
        BusOperLog log = new BusOperLog("任务开始", BusRole.getRole(LoginHelper.getBusRole()), bo.getTaskId(), 1);
        busOperLogMapper.insert(log);
        this.addUserWorkerBiz(bo);
        return baseMapper.updateTaskEnrollCheckStatusSuccess(bo) > 0;
    }

    private void addUserWorkerBiz(MerTaskEnrollBo bo){

        MerTaskVo taskVo = this.merTaskMapper.selectMerTaskById(bo.getTaskId());
        int busType = taskVo.getBusType();
        long sydId = taskVo.getSydId();
        long merId = taskVo.getMerId();

        Map paraMap = new HashMap();
        paraMap.put("merId",merId);
        paraMap.put("sydId",sydId);
        paraMap.put("busType",busType);
        paraMap.put("workIds",bo.getIds());

        List<UserWorkerBusinessVo> uwList = this.userWorkerBusinessMapper.selUserWorkBizByCon(paraMap);
        Map<Long, UserWorkerBusinessVo> map = uwList.stream()
            .collect(Collectors.toMap(UserWorkerBusinessVo::getWorkId, obj -> obj));

        List<UserWorkerBusiness> uwbList = new ArrayList<>();
        for(Long wordId: bo.getIds()){
            if(map.get(wordId) == null){
                UserWorkerBusiness  uwb = new UserWorkerBusiness();
                uwb.setWorkId(wordId);
                uwb.setBusType(busType);
                uwb.setMerId(merId);
                uwb.setSydId(sydId);
                uwb.setMerNo(taskVo.getMerNo());
                uwb.setSydNo(taskVo.getSydNo());
                uwb.setOpId(taskVo.getOpId());
                uwb.setOpNo(taskVo.getOpNo());
                uwb.setChannelId(taskVo.getChannelId());
                uwb.setChannelNo(taskVo.getChannelNo());
                uwb.setSignStatus(0);
                uwb.setCreateTime(new Date());
                uwb.setCreateBy(LoginHelper.getUserId());
                uwbList.add(uwb);
            }
        }
        if(!uwbList.isEmpty()){
            this.userWorkerBusinessMapper.insertBatch(uwbList);
        }
    }

    /**
     * 查询任务的报名列表
     */
    @Override
    public Boolean acceptanceEnrollByBo(MerTaskEnrollBo bo) {
        MerTaskEnroll update = MapstructUtils.convert(bo, MerTaskEnroll.class);
        if(null == bo.getTaskId()){
            throw new IllegalArgumentException("项目ID不能为空");
        }
        if(null == bo.getId() ){
            throw new IllegalArgumentException("子项目ID不能为空");
        }

        if(null == bo.getTaskStatus() ){
            throw new IllegalArgumentException("完工状态不能为空");
        }

        Integer busRole = LoginHelper.getBusRole();
        if(busRole != BusRole.SERVICE.getId()
            && busRole != BusRole.MERCHANT.getId() ){
            throw new IllegalArgumentException("当前用户没有审核项目权限，请联系管理员");
        }

        boolean result = baseMapper.updateTaskEnrollTaskStatus(bo) > 0;

        if(3 == bo.getTaskStatus()){
            //判断是否项目结束
            MerTask task = new MerTask();
            task.setId(bo.getTaskId());

            if(merTaskMapper.updateEndById(task) > 0){
                BusOperLog log = new BusOperLog("任务结束", BusRole.getRole(LoginHelper.getBusRole()), bo.getTaskId(), 1);
                busOperLogMapper.insert(log);
            }
        }
        return result;
    }


    /**
     * 查询任务的报名列表
     */
    @Override
    public List<MerTaskEnrollVo> queryList(MerTaskEnrollBo bo) {
        LambdaQueryWrapper<MerTaskEnroll> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private QueryWrapper<MerTaskEnroll> buildQueryWrapper2(MerTaskEnrollBo bo) {
        Map<String, Object> params = bo.getParams();
        QueryWrapper<MerTaskEnroll> lqw = Wrappers.query();

        lqw.eq(bo.getId() != null, "mer_task_enroll.id", bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getNo()), "mer_task_enroll.no", bo.getNo());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskNo()), "mer_task_enroll.task_no", bo.getTaskNo());
        lqw.eq(bo.getTaskId() != null, "mer_task_enroll.task_id", bo.getTaskId());
        lqw.eq(bo.getWorkId() != null, "mer_task_enroll.work_id", bo.getWorkId());
        lqw.eq(bo.getVerifyStatus() != null, "mer_task_enroll.verify_status", bo.getVerifyStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getVerifyBy()), "mer_task_enroll.verify_by", bo.getVerifyBy());
        lqw.eq(bo.getTaskStatus() != null, "mer_task_enroll.task_status", bo.getTaskStatus());
        lqw.eq(bo.getSettlementStatus() != null, "mer_task_enroll.settlement_status", bo.getSettlementStatus());
        lqw.eq(bo.getAddTime() != null, "mer_task_enroll.add_time", bo.getAddTime());
        return lqw;
    }

    private LambdaQueryWrapper<MerTaskEnroll> buildQueryWrapper(MerTaskEnrollBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<MerTaskEnroll> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getNo()), MerTaskEnroll::getNo, bo.getNo());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskNo()), MerTaskEnroll::getTaskNo, bo.getTaskNo());
        lqw.eq(bo.getTaskId() != null, MerTaskEnroll::getTaskId, bo.getTaskId());
        lqw.eq(bo.getWorkId() != null, MerTaskEnroll::getWorkId, bo.getWorkId());
        lqw.eq(StringUtils.isNotBlank(bo.getWorkOpenid()), MerTaskEnroll::getWorkOpenid, bo.getWorkOpenid());
        lqw.eq(bo.getVerifyStatus() != null, MerTaskEnroll::getVerifyStatus, bo.getVerifyStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getVerifyBy()), MerTaskEnroll::getVerifyBy, bo.getVerifyBy());
        lqw.eq(bo.getVerifyTime() != null, MerTaskEnroll::getVerifyTime, bo.getVerifyTime());
        lqw.eq(bo.getTaskStatus() != null, MerTaskEnroll::getTaskStatus, bo.getTaskStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskRemark()), MerTaskEnroll::getTaskRemark, bo.getTaskRemark());
        lqw.eq(bo.getSettlementStatus() != null, MerTaskEnroll::getSettlementStatus, bo.getSettlementStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskConfirmFile()), MerTaskEnroll::getTaskConfirmFile, bo.getTaskConfirmFile());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskDesc()), MerTaskEnroll::getTaskDesc, bo.getTaskDesc());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskPic()), MerTaskEnroll::getTaskPic, bo.getTaskPic());
        lqw.eq(bo.getAddTime() != null, MerTaskEnroll::getAddTime, bo.getAddTime());
        return lqw;
    }

    /**
     * 新增任务的报名
     */
    @Override
    public Boolean insertByBo(MerTaskEnrollBo bo) {
        MerTaskEnroll add = MapstructUtils.convert(bo, MerTaskEnroll.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改任务的报名
     */
    @Override
    public Boolean updateByBo(MerTaskEnrollBo bo) {
        MerTaskEnroll update = MapstructUtils.convert(bo, MerTaskEnroll.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }




    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(MerTaskEnroll entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除任务的报名
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
