package com.cf.imes.module.system.service.labeltemplate;

import cn.hutool.core.collection.CollectionUtil;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import java.util.stream.Collectors;
import com.cf.imes.module.system.controller.admin.labeltemplate.vo.*;
import com.cf.imes.module.system.dal.dataobject.labeltemplate.LabelTemplateDO;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.system.dal.mysql.labeltemplate.LabelTemplateMapper;
import javax.annotation.Resource;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;

/**
 * 标签模板 Service 实现类
 *
 * @author 晨丰科技
 */
@Service
@Validated
@Slf4j
public class LabelTemplateServiceImpl implements LabelTemplateService {

    @Resource
    private LabelTemplateMapper labelTemplateMapper;

    @Override
    public Long createLabelTemplate(LabelTemplateSaveReqVO createReqVO) {
        // 插入
        LabelTemplateDO labelTemplate = BeanUtils.toBean(createReqVO, LabelTemplateDO.class);
        labelTemplateMapper.insert(labelTemplate);
        // 返回
        return labelTemplate.getId();
    }

    @Override
    public void updateLabelTemplate(LabelTemplateSaveReqVO updateReqVO) {
        // 校验存在
        validateLabelTemplateExists(updateReqVO.getId());
        // 更新
        LabelTemplateDO updateObj = BeanUtils.toBean(updateReqVO, LabelTemplateDO.class);
        labelTemplateMapper.updateById(updateObj);
    }

    @Override
    public void deleteLabelTemplate(Long id) {
        // 校验存在
        LabelTemplateDO labelTemplateDO = labelTemplateMapper.selectById(id);
        if (labelTemplateDO == null) {
            throw exception(LABEL_TEMPLATE_NOT_EXISTS);
        }
        Boolean isDefault = labelTemplateDO.getIsDefault();
        if(isDefault) {
            throw exception(DEFAULT_NOT_DELETED);
        }
        labelTemplateMapper.deleteById(id);
    }

    private void validateLabelTemplateExists(Long id) {
        if (labelTemplateMapper.selectById(id) == null) {
            throw exception(LABEL_TEMPLATE_NOT_EXISTS);
        }
    }

    @Override
    public LabelTemplateRespVO getLabelTemplate(Long id) {
        LabelTemplateDO labelTemplateDO = labelTemplateMapper.selectById(id);
        LabelTemplateRespVO labelTemplateRespVO = BeanUtils.toBean(labelTemplateDO, LabelTemplateRespVO.class);
        return labelTemplateRespVO;
    }

    @Override
    public PageResult<LabelTemplateDO> getLabelTemplatePage(LabelTemplatePageReqVO pageReqVO) {
        return labelTemplateMapper.selectPage(pageReqVO);
    }


    @Override
    public Map<String, List<LabelTemplateRespVO>> getGroupList() {
        List<LabelTemplateDO> labelTemplateDOS = labelTemplateMapper.selectList();
        List<LabelTemplateRespVO> labelTemplateRespVOS = BeanUtils.toBean(labelTemplateDOS, LabelTemplateRespVO.class);
        return labelTemplateRespVOS.stream().collect(Collectors.groupingBy(LabelTemplateRespVO::getType));
    }

    @Override
    public LabelTemplateRespVO getDefaultLabelTemplate(String type) {
        List<LabelTemplateDO> labelTemplateDOS = labelTemplateMapper.selectList(new LambdaQueryWrapperX<LabelTemplateDO>()
                .eq(LabelTemplateDO::getIsDefault, Boolean.TRUE)
                .eq(LabelTemplateDO::getType, type)
        );
        if(CollectionUtil.isNotEmpty(labelTemplateDOS)) {
            if (labelTemplateDOS.size() > 1) {
                throw exception(DEFAULT_TEMPLATE_COUNT);
            }
            LabelTemplateDO labelTemplateDO = labelTemplateDOS.get(0);
            LabelTemplateRespVO labelTemplateRespVO = BeanUtils.toBean(labelTemplateDO, LabelTemplateRespVO.class);
            return labelTemplateRespVO;
        }
        throw exception(DEFAULT_LABEL_NOT_EXISTS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setDefaultTemplate(Long id) {
        LabelTemplateDO labelTemplateDO = labelTemplateMapper.selectById(id);
        if(Objects.isNull(labelTemplateDO)) {
            throw exception(LABEL_TEMPLATE_NOT_EXISTS);
        }
        List<LabelTemplateDO> labelTemplateDOS = labelTemplateMapper.selectList(new LambdaQueryWrapperX<LabelTemplateDO>()
                .eq(LabelTemplateDO::getIsDefault, Boolean.TRUE)
                .eq(LabelTemplateDO::getType, labelTemplateDO.getType())
        );
        if(CollectionUtil.isEmpty(labelTemplateDOS) || labelTemplateDOS.size()>1) {
            throw exception(DEFAULT_TEMPLATE_COUNT);
        }
        LabelTemplateDO templateDO = new LabelTemplateDO();
        templateDO.setId(labelTemplateDOS.get(0).getId());
        templateDO.setIsDefault(Boolean.FALSE);
        labelTemplateMapper.updateById(templateDO);

        labelTemplateDO.setIsDefault(Boolean.TRUE);
        labelTemplateMapper.updateById(labelTemplateDO);

        return Boolean.TRUE;
    }

}