package cn.axzo.workflow.core.service.impl;

import cn.axzo.workflow.common.model.request.category.CategoryConfigCreateDTO;
import cn.axzo.workflow.common.model.request.category.CategoryConfigSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.repository.entity.ExtAxDict;
import cn.axzo.workflow.core.repository.entity.ExtAxDictConf;
import cn.axzo.workflow.core.repository.mapper.ExtAxDictConfMapper;
import cn.axzo.workflow.core.repository.mapper.ExtAxDictMapper;
import cn.axzo.workflow.core.service.CategoryConfigService;
import cn.axzo.workflow.core.service.converter.CategoryConfigConverter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

import static cn.axzo.workflow.core.common.code.CategoryRespCode.CATEGORY_CONFIG_EXISTS;

/**
 * 分类黑白名单配置服务
 *
 * @author wangli
 * @since 2023/12/26 11:18
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CategoryConfigServiceImpl extends ServiceImpl<ExtAxDictConfMapper, ExtAxDictConf> implements CategoryConfigService {
    @Resource
    private ExtAxDictMapper dictMapper;
    @Resource
    private ExtAxDictConfMapper dictConfMapper;
    private final CategoryConfigConverter categoryConfigConverter;

    @Override
    public void create(CategoryConfigCreateDTO dto) {
        CategoryConfigSearchDTO searchDTO = new CategoryConfigSearchDTO();
        searchDTO.setDictId(dto.getDictId());
        searchDTO.setConfigType(dto.getConfigType());
        searchDTO.setWorkspaceIds(dto.getWorkspaceIds());
        List<CategoryConfigItemVO> list = configSearch(searchDTO).getList();
        if (!list.isEmpty()) {
            ExtAxDict extAxDict = dictMapper.selectById(dto.getDictId());
            throw new WorkflowEngineException(CATEGORY_CONFIG_EXISTS, extAxDict.getLabel(),
                    Objects.equals(dto.getConfigType(), "white") ? "白名单" : "黑名单");
        }

        dto.getWorkspaceIds().forEach(workspaceId -> {
            ExtAxDictConf config = new ExtAxDictConf();
            config.setDictId(dto.getDictId());
            config.setConfigType(dto.getConfigType());
            config.setWorkspaceId(workspaceId);
            config.setOperationName(dto.getOperationName());
            dictConfMapper.insert(config);
        });
    }

    @Override
    public Boolean delete(Long id) {
        dictConfMapper.deleteById(id);
        return true;
    }

    @Override
    public BpmPageResult<CategoryConfigItemVO> configSearch(CategoryConfigSearchDTO dto) {
        LambdaQueryWrapper<ExtAxDictConf> queryWrapper = Wrappers.lambdaQuery(ExtAxDictConf.class)
                .eq(Objects.nonNull(dto.getDictId()), ExtAxDictConf::getDictId, dto.getDictId())
                .eq(StringUtils.hasLength(dto.getConfigType()), ExtAxDictConf::getConfigType, dto.getConfigType())
                .eq(Objects.nonNull(dto.getWorkspaceId()), ExtAxDictConf::getWorkspaceId, dto.getWorkspaceId())
                .in(!CollectionUtils.isEmpty(dto.getWorkspaceIds()), ExtAxDictConf::getWorkspaceId,
                        dto.getWorkspaceIds())
                .like(StringUtils.hasLength(dto.getOperationName()), ExtAxDictConf::getOperationName,
                        dto.getOperationName())
                .eq(ExtAxDictConf::getIsDelete, false)
                .orderByDesc(ExtAxDictConf::getCreateAt);
        Page<ExtAxDictConf> page = dictConfMapper.selectPage(new Page<>(dto.getPageNo(), dto.getPageSize()),
                queryWrapper);

        List<CategoryConfigItemVO> configVos = categoryConfigConverter.toVos(page.getRecords());
        return new BpmPageResult<>(configVos, page.getTotal());
    }

    @Override
    public List<CategoryConfigItemVO> list(Long dictId, String configType) {
        LambdaQueryWrapper<ExtAxDictConf> queryWrapper = Wrappers.lambdaQuery(ExtAxDictConf.class)
                .eq(Objects.nonNull(dictId), ExtAxDictConf::getDictId, dictId)
                .eq(StringUtils.hasLength(configType), ExtAxDictConf::getConfigType, configType)
                .eq(ExtAxDictConf::getIsDelete, false)
                .orderByDesc(ExtAxDictConf::getCreateAt);
        List<ExtAxDictConf> extAxDictConfs = dictConfMapper.selectList(queryWrapper);
        return categoryConfigConverter.toVos(extAxDictConfs);
    }
}
