package com.njcn.bpm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.bpm.enums.BpmResponseEnum;
import com.njcn.bpm.mapper.BpmCategoryMapper;
import com.njcn.bpm.pojo.param.BpmCategoryParam;
import com.njcn.bpm.pojo.po.BpmCategory;
import com.njcn.bpm.pojo.vo.BpmCategoryVO;
import com.njcn.bpm.service.IBpmCategoryService;
import com.njcn.bpm.utils.BeanUtils;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.web.factory.PageFactory;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * BPM 流程分类 Service 实现类
 *
 * @author hongawen
 */
@Service
@Validated
public class BpmCategoryServiceImpl extends ServiceImpl<BpmCategoryMapper, BpmCategory> implements IBpmCategoryService {


    @Override
    public String createCategory(BpmCategoryParam bpmCategoryParam) {
        // 校验唯一
        checkCategoryName(bpmCategoryParam, false);
        checkCategoryCode(bpmCategoryParam, false);
        // 插入
        BpmCategory category = BeanUtils.toBean(bpmCategoryParam, BpmCategory.class);
        category.setState(DataStateEnum.ENABLE.getCode());
        this.baseMapper.insert(category);
        return category.getId();
    }

    @Override
    public void updateCategory(BpmCategoryParam.BpmCategoryUpdateParam updateParam) {
        // 校验唯一
        checkCategoryName(updateParam, true);
        checkCategoryCode(updateParam, true);
        // 更新
        BpmCategory updateObj = BeanUtils.toBean(updateParam, BpmCategory.class);
        this.baseMapper.updateById(updateObj);
    }


    @Override
    public void deleteCategory(List<String> ids) {
        this.lambdaUpdate().set(BpmCategory::getState, DataStateEnum.DELETED.getCode())
                .in(BpmCategory::getId, ids)
                .update();
    }


    @Override
    public Page<BpmCategoryVO> getCategoryPage(BpmCategoryParam.BpmCategoryQueryParam bpmCategoryQueryParam) {
        QueryWrapper<BpmCategoryVO> categoryVOQueryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(bpmCategoryQueryParam.getSearchValue())) {
            categoryVOQueryWrapper.like("bpm_category.name", bpmCategoryQueryParam.getSearchValue());
        }

        if (StrUtil.isNotBlank(bpmCategoryQueryParam.getCode())) {
            categoryVOQueryWrapper.like("bpm_category.code", bpmCategoryQueryParam.getCode());
        }
        categoryVOQueryWrapper.eq("bpm_category.state", DataStateEnum.ENABLE.getCode());
        categoryVOQueryWrapper.orderByAsc("bpm_category.sort");
        return this.baseMapper.page(new Page<>(PageFactory.getPageNum(bpmCategoryQueryParam), PageFactory.getPageSize(bpmCategoryQueryParam)), categoryVOQueryWrapper);

    }

    @Override
    public List<BpmCategory> getCategoryListById(Collection<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<BpmCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(BpmCategory::getId,ids);
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public List<BpmCategory> getCategoryList() {
        LambdaQueryWrapper<BpmCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(BpmCategory::getId,BpmCategory::getName)
                .eq(BpmCategory::getState,DataStateEnum.ENABLE.getCode());
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }


    private void checkCategoryName(BpmCategoryParam bpmCategoryParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<BpmCategory> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //判断流程表单的名称
        categoryLambdaQueryWrapper
                .eq(BpmCategory::getName, bpmCategoryParam.getName())
                .eq(BpmCategory::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (bpmCategoryParam instanceof BpmCategoryParam.BpmCategoryUpdateParam) {
                categoryLambdaQueryWrapper.ne(BpmCategory::getId, ((BpmCategoryParam.BpmCategoryUpdateParam) bpmCategoryParam).getId());
            }
        }
        int nameCountByAccount = this.count(categoryLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (nameCountByAccount >= 1) {
            throw new BusinessException(BpmResponseEnum.REPEAT_CATEGORY_NAME_FORM);
        }
    }

    private void checkCategoryCode(BpmCategoryParam bpmCategoryParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<BpmCategory> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //判断流程表单的名称
        categoryLambdaQueryWrapper
                .eq(BpmCategory::getCode, bpmCategoryParam.getCode())
                .eq(BpmCategory::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (bpmCategoryParam instanceof BpmCategoryParam.BpmCategoryUpdateParam) {
                categoryLambdaQueryWrapper.ne(BpmCategory::getId, ((BpmCategoryParam.BpmCategoryUpdateParam) bpmCategoryParam).getId());
            }
        }
        int nameCountByAccount = this.count(categoryLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (nameCountByAccount >= 1) {
            throw new BusinessException(BpmResponseEnum.REPEAT_CATEGORY_CODE_FORM);
        }
    }


}