package org.dromara.zjk.learning_world.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.common.core.exception.ServiceException;
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.zjk.domain.vo.ZjkExpertVo;
import org.dromara.zjk.learning_world.domain.excel.ZjkLearningActivityExcel;
import org.dromara.zjk.learning_world.enums.course.ActivityStatusEnum;
import org.dromara.zjk.learning_world.enums.course.ActivityTypeEnum;
import org.dromara.zjk.mapper.ZjkExpertMapper;
import org.dromara.zjk.utils.EnumUtil;
import org.springframework.stereotype.Service;
import org.dromara.zjk.learning_world.domain.bo.ZjkLearningActivityBo;
import org.dromara.zjk.learning_world.domain.vo.ZjkLearningActivityVo;
import org.dromara.zjk.learning_world.domain.entity.ZjkLearningActivity;
import org.dromara.zjk.learning_world.mapper.ZjkLearningActivityMapper;
import org.dromara.zjk.learning_world.service.IZjkLearningActivityService;

import java.rmi.server.ServerCloneException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动管理Service业务层处理
 *
 * @author ygh
 * @date 2024-11-08
 */
@RequiredArgsConstructor
@Service
public class ZjkLearningActivityServiceImpl implements IZjkLearningActivityService {

    private final ZjkLearningActivityMapper baseMapper;

    private final ZjkExpertMapper zjkExpertMapper;

    /**
     * 查询活动管理
     *
     * @param id 主键
     * @return 活动管理
     */
    @Override
    public ZjkLearningActivityVo queryById(Long id) {
        return baseMapper.getById(id);
    }

    /**
     * 分页查询活动管理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 活动管理分页列表
     */
    @Override
    public TableDataInfo<ZjkLearningActivityVo> queryPageList(ZjkLearningActivityBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZjkLearningActivity> lqw = buildQueryWrapper(bo);
        Page<ZjkLearningActivityVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<ZjkLearningActivityVo> records = result.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return TableDataInfo.build(result);
        }
        Set<Long> userIdSet = records.stream().map(ZjkLearningActivityVo::getUserId).collect(Collectors.toSet());
        List<ZjkExpertVo> zjkExpertVos = zjkExpertMapper.selectByUserIds(userIdSet);
        if (CollectionUtil.isEmpty(zjkExpertVos)) {
            return TableDataInfo.build(result);
        }
        Map<Long, ZjkExpertVo> collect = zjkExpertVos.stream().collect(Collectors.toMap(ZjkExpertVo::getUserId, v -> v));
        for (ZjkLearningActivityVo record : records) {
            Long userId = record.getUserId();
            if (collect.containsKey(userId)) {
                ZjkExpertVo zjkExpertVo = collect.get(userId);
                if (zjkExpertVo != null) {
                    record.setUserName(zjkExpertVo.getUserName());
                    record.setDeptName(zjkExpertVo.getDeptName());
                }
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的活动管理列表
     *
     * @param bo 查询条件
     * @return 活动管理列表
     */
    @Override
    public List<ZjkLearningActivityVo> queryList(ZjkLearningActivityBo bo) {
        LambdaQueryWrapper<ZjkLearningActivity> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZjkLearningActivity> buildQueryWrapper(ZjkLearningActivityBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZjkLearningActivity> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getActivityName()), ZjkLearningActivity::getActivityName, bo.getActivityName());
        lqw.eq(StringUtils.isNotBlank(bo.getActivityClassify()), ZjkLearningActivity::getActivityClassify, bo.getActivityClassify());
        lqw.le(bo.getActivityEndTime() != null, ZjkLearningActivity::getActivityEndTime, bo.getActivityEndTime());
        lqw.ge(bo.getActivityStartTime() != null, ZjkLearningActivity::getActivityStartTime, bo.getActivityStartTime());
        lqw.eq(StringUtils.isNotBlank(bo.getActivityAddress()), ZjkLearningActivity::getActivityAddress, bo.getActivityAddress());
        lqw.eq(bo.getActivityNum() != null, ZjkLearningActivity::getActivityNum, bo.getActivityNum());
        lqw.eq(StringUtils.isNotBlank(bo.getActivityPic()), ZjkLearningActivity::getActivityPic, bo.getActivityPic());
        lqw.eq(StringUtils.isNotBlank(bo.getActivityContent()), ZjkLearningActivity::getActivityContent, bo.getActivityContent());
        lqw.eq(StringUtils.isNotBlank(bo.getIsPublic()), ZjkLearningActivity::getIsPublic, bo.getIsPublic());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ZjkLearningActivity::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getActivityStatus()), ZjkLearningActivity::getActivityStatus, bo.getActivityStatus());
        return lqw;
    }

    /**
     * 新增活动管理
     *
     * @param bo 活动管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ZjkLearningActivityBo bo) {
        ZjkLearningActivity add = MapstructUtils.convert(bo, ZjkLearningActivity.class);
        validEntityBeforeSave(add);
        Date activityStartTime = add.getActivityStartTime();
        Date activityEndTime = add.getActivityEndTime();
        add.setUserId(LoginHelper.getUserId());
        if (!activityEndTime.after(activityStartTime)) {
            throw new ServiceException("开始时间必须小于结束时间");
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改活动管理
     *
     * @param bo 活动管理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ZjkLearningActivityBo bo) {
        ZjkLearningActivity update = MapstructUtils.convert(bo, ZjkLearningActivity.class);
        validEntityBeforeSave(update);
        Long id = update.getId();
        ZjkLearningActivityVo zjkLearningActivityVo = baseMapper.selectVoById(id);
        if (zjkLearningActivityVo == null) {
            return false;
        }
        String activityStatus = zjkLearningActivityVo.getActivityStatus();
        if (!activityStatus.equals(ActivityStatusEnum.DIDN_T_START.getCode())) {
            throw new ServiceException("活动无法修改，请确认活动状态");
        }
        return baseMapper.updateById(update) > 0;
    }

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

    /**
     * 校验并批量删除活动管理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public List<ZjkLearningActivityExcel> exportList(ZjkLearningActivityBo bo) {
        List<ZjkLearningActivityVo> zjkLearningActivityVos = queryList(bo);
        if (CollectionUtil.isEmpty(zjkLearningActivityVos)) {
            return List.of();
        }
        List<ZjkLearningActivityExcel> zjkLearningActivityExcels = BeanUtil.copyToList(zjkLearningActivityVos, ZjkLearningActivityExcel.class);
        for (ZjkLearningActivityExcel excel : zjkLearningActivityExcels) {
            String activityStatus = excel.getActivityStatus();
            String nameByCode = EnumUtil.getNameByCode(ActivityStatusEnum.class, activityStatus);
            if (StringUtils.isNotBlank(nameByCode)) {
                excel.setActivityStatus(nameByCode);
            }
            String activityClassify = excel.getActivityClassify();
            String classifyByCode = EnumUtil.getNameByCode(ActivityTypeEnum.class, activityClassify);
            if (StringUtils.isNotBlank(classifyByCode)) {
                excel.setActivityStatusName(classifyByCode);
            }
        }


        return zjkLearningActivityExcels;
    }

    @Override
    public int updateStatus(ZjkLearningActivityBo bo) {
        Long id = bo.getId();
        ZjkLearningActivity zjkLearningActivity = baseMapper.selectById(id);
        if (zjkLearningActivity == null) {
            throw new ServiceException("无效id");
        }
        zjkLearningActivity.setStatus(bo.getStatus());
        zjkLearningActivity.setTakedownTime(new Date());
        return baseMapper.updateById(zjkLearningActivity);
    }
}
