package com.njcn.gather.system.dictionary.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
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.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.db.mybatisplus.constant.DbConstant;
import com.njcn.gather.system.dictionary.mapper.DictPqMapper;
import com.njcn.gather.system.dictionary.pojo.param.DictPqParam;
import com.njcn.gather.system.dictionary.pojo.po.DictPq;
import com.njcn.gather.system.dictionary.service.IDictDataService;
import com.njcn.gather.system.dictionary.service.IDictPqService;
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author caozehui
 */
@Service
@RequiredArgsConstructor
public class DictPqServiceImpl extends ServiceImpl<DictPqMapper, DictPq> implements IDictPqService {

    private final IDictDataService dictDataService;

    @Override
    public Page<DictPq> listDictPqs(DictPqParam.QueryParam queryParam) {
        QueryWrapper<DictPq> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(queryParam)) {
            queryWrapper.like(StrUtil.isNotBlank(queryParam.getName()), "sys_dict_pq.name", queryParam.getName())
                    .like(StrUtil.isNotBlank(queryParam.getOtherName()), "sys_dict_pq.other_name", queryParam.getOtherName())
                    .like(StrUtil.isNotBlank(queryParam.getShowName()), "sys_dict_pq.show_name", queryParam.getShowName())
                    .eq(StrUtil.isNotBlank(queryParam.getDataType()), "sys_dict_pq.data_type", queryParam.getDataType())
                    .eq(StrUtil.isNotBlank(queryParam.getClassId()), "sys_dict_pq.class_id", queryParam.getClassId());
            //排序
            if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
                queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
            } else {
                //没有排序参数，默认根据sort字段排序，没有排序字段的，根据updateTime更新时间排序
                queryWrapper.orderBy(true, true, "sys_dict_pq.sort").orderByDesc("sys_dict_pq.update_time");
            }
        } else {
            queryWrapper.orderBy(true, true, "sys_dict_pq.sort").orderByDesc("sys_dict_pq.update_time");
        }
        queryWrapper.ne("sys_dict_pq.state", DataStateEnum.DELETED.getCode());
        return this.baseMapper.selectPage(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
    }

    @Override
    @Transactional
    public boolean addDictPq(DictPqParam dictPqParam) {
        dictPqParam.setName(dictPqParam.getName().trim());
        checkDicPqName(dictPqParam, false);
        DictPq dictPq = new DictPq();
        BeanUtil.copyProperties(dictPqParam, dictPq);
        //默认为正常状态
        dictPq.setState(DataStateEnum.ENABLE.getCode());
        return this.save(dictPq);
    }

    @Override
    @Transactional
    public boolean updateDictPq(DictPqParam.UpdateParam updateParam) {
        updateParam.setName(updateParam.getName().trim());
        checkDicPqName(updateParam, true);
        DictPq dictPq = new DictPq();
        BeanUtil.copyProperties(updateParam, dictPq);
        return this.updateById(dictPq);
    }

    @Override
    @Transactional
    public boolean deleteDictPq(List<String> ids) {
        dictDataService.deleteDictDataByDictTypeId(ids);
        return this.lambdaUpdate()
                .set(DictPq::getState, DataStateEnum.DELETED.getCode())
                .in(DictPq::getId, ids)
                .update();
    }

    /**
     * 校验参数，检查同一数据模型及相别下是否存在相同名称的字典项
     *
     * @param dictPqParam   字典项参数
     * @param isExcludeSelf 是否排除自己
     */
    private void checkDicPqName(DictPqParam dictPqParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<DictPq> dictPqLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dictPqLambdaQueryWrapper
                .eq(StrUtil.isNotBlank(dictPqParam.getDataType()), DictPq::getDataType, dictPqParam.getDataType())
                .eq(StrUtil.isNotBlank(dictPqParam.getName()), DictPq::getName, dictPqParam.getName())
                .eq(StrUtil.isNotBlank(dictPqParam.getPhase()), DictPq::getPhase, dictPqParam.getPhase())
                .eq(DictPq::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (dictPqParam instanceof DictPqParam.UpdateParam) {
                dictPqLambdaQueryWrapper.ne(DictPq::getId, ((DictPqParam.UpdateParam) dictPqParam).getId());
            }
        }
        int countByAccount = this.count(dictPqLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(SystemResponseEnum.DICT_PQ_NAME_EXIST);
        }
    }
}
