package com.njcn.system.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.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.db.constant.DbConstant;
import com.njcn.device.pq.api.PqDevTypeClient;
import com.njcn.device.pq.pojo.po.PqDevType;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.enums.SystemResponseEnum;
import com.njcn.system.mapper.DictDataMapper;
import com.njcn.system.pojo.constant.SystemType;
import com.njcn.system.pojo.param.DictDataParam;
import com.njcn.system.pojo.po.Config;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.DictType;
import com.njcn.system.pojo.vo.DictDataVO;
import com.njcn.system.service.IConfigService;
import com.njcn.system.service.IDictDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.system.service.IDictTypeService;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author hongawen
 * @since 2021-12-13
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements IDictDataService {

    private final IConfigService iConfigService;
    private final IDictTypeService dictTypeService;
    private final PqDevTypeClient pqDevTypeClient;


    @Override
    public Page<DictDataVO> listDictData(DictDataParam.DictDataQueryParam queryParam) {
        QueryWrapper<DictDataVO> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(queryParam)) {
            //查询参数不为空，进行条件填充
            if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
                //字典类型表，仅提供名称、编码模糊查询
                queryWrapper
                        .and(param -> param.like("sys_dict_data.name", queryParam.getSearchValue())
                                .or().like("sys_dict_data.code", queryParam.getSearchValue()));
            }
            //排序
            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_data.sort");
            }
        }
        queryWrapper.ne("sys_dict_data.state", DataStateEnum.DELETED.getCode());
        //初始化分页数据
        return this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
    }

    @Override
    public boolean addDictData(DictDataParam dictDataParam) {
        checkDicDataName(dictDataParam, false);
        DictData dictData = new DictData();
        BeanUtil.copyProperties(dictDataParam, dictData);
        //默认为正常状态
        dictData.setState(DataStateEnum.ENABLE.getCode());
        return this.save(dictData);
    }

    @Override
    public boolean updateDictData(DictDataParam.DictDataUpdateParam updateParam) {
        checkDicDataName(updateParam, true);
        DictData dictData = new DictData();
        BeanUtil.copyProperties(updateParam, dictData);
        return this.updateById(dictData);
    }

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

    @Override
    public Page<DictDataVO> getTypeIdData(DictDataParam.DicTypeIdQueryParam queryParam) {
        QueryWrapper<DictDataVO> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(queryParam)) {
            //查询参数不为空，进行条件填充
            if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
                //字典类型表，仅提供名称、编码模糊查询
                queryWrapper
                        .and(param -> param.like("sys_dict_data.name", queryParam.getSearchValue())
                                .or().like("sys_dict_data.code", queryParam.getSearchValue()));
            }
            //排序
            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_data.sort");
            }
        }
        queryWrapper.ne("sys_dict_data.state", DataStateEnum.DELETED.getCode());
        queryWrapper.eq("sys_dict_data.type_id", queryParam.getTypeId());
        //初始化分页数据
        return this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
    }

    @Override
    public DictData getDicDataById(String dicIndex) {

        return this.baseMapper.selectById(dicIndex);
    }

    @Override
    public List<DictData> getDicDataByTypeName(String dictTypeName) {
        if(DicDataTypeEnum.DEV_TYPE.getName().equals(dictTypeName)){
            return  getDicData();
        }
        return this.baseMapper.getDicDataByTypeName(dictTypeName);
    }

    @Override
    public List<DictData> getDicDataByTypeCode(String dictTypeCode) {
        if(DicDataTypeEnum.DEV_TYPE.getCode().equals(dictTypeCode)){
            return  getDicData();
        }
        return this.baseMapper.getDicDataByTypeCode(dictTypeCode);
    }


    public List<DictData> getDicData() {
        List<DictData> info=new ArrayList<>();
        List<PqDevType> data = pqDevTypeClient.getDevTypeList().getData();
        DictData dictData;
        for (PqDevType datum : data) {
            dictData=new DictData();
            dictData.setId(datum.getId());
            dictData.setName(datum.getName());
            info.add(dictData);
        }
        return info;
    }

    @Override
    public DictData getDicDataByName(String dicName) {
        return this.baseMapper.getDicDataByName(dicName);
    }

    @Override
    public DictData getDicDataByNameAndType(String dicName, String typeName) {
        return this.baseMapper.getDicDataByNameAndType(dicName, typeName);
    }

    @Override
    public DictData getDicDataByCodeAndType(String dicCode, String typeCode) {
        return this.baseMapper.getDicDataByCodeAndType(dicCode, typeCode);
    }

    @Override
    public DictData getDicDataByCode(String code) {
        return this.baseMapper.getDicDataByCode(code);
    }

    @Override
    public List<DictData> getLoadTypeBySys() {
        List<DictData> list;
        Config config = iConfigService.lambdaQuery()
                .eq(Config::getState, DataStateEnum.ENABLE.getCode())
                .one();
        if (Objects.equals(config.getType(), SystemType.ENTERPRISE_SYSTEM)) {
            List<DictData> dataList = this.baseMapper.getDicDataByTypeName(DicDataTypeEnum.INDICATOR_TYPE.getName());
            return dataList.stream().filter(item -> Objects.equals(item.getName(), DicDataEnum.XBDY_ENUM.getName()) || Objects.equals(item.getName(), DicDataEnum.XBDL_ENUM.getName())).collect(Collectors.toList());
        } else {
            list = this.baseMapper.getDicDataByTypeName(DicDataTypeEnum.INDICATOR_TYPE.getName()).stream().sorted(Comparator.comparing(DictData::getSort)).collect(Collectors.toList());
        }
        return list;
    }

    @Override
    public DictData getDicDataByNameAndTypeName(String dicTypeName, String dicDataName) {
        return this.baseMapper.getDicDataByNameAndTypeName(dicTypeName, dicDataName);
    }

    @Override
    public DictData addDictData(String dicTypeName, String dicDataName) {
        //根据type名称获取index，如果不存在该字典类型，则新增该字典类型
        DictType dictType = dictTypeService.getByName(dicTypeName);
        if (Objects.isNull(dictType)) {
            dictType = dictTypeService.addByName(dicTypeName);
        }
        DictData dictData = new DictData();
        dictData.setTypeId(dictType.getId());
        dictData.setName(dicDataName);
        dictData.setCode(dicDataName);
        dictData.setSort(0);
        dictData.setLevel(0);
        dictData.setState(DataStateEnum.ENABLE.getCode());
        this.save(dictData);
        return dictData;
    }

    /**
     * 校验参数，检查是否存在相同名称的字典类型
     */
    private void checkDicDataName(DictDataParam dictDataParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<DictData> dictDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dictDataLambdaQueryWrapper
                .eq(DictData::getName, dictDataParam.getName())
                .eq(DictData::getTypeId, dictDataParam.getTypeId())
                .eq(DictData::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (dictDataParam instanceof DictDataParam.DictDataUpdateParam) {
                dictDataLambdaQueryWrapper.ne(DictData::getId, ((DictDataParam.DictDataUpdateParam) dictDataParam).getId());
            }
        }
        int countByAccount = this.count(dictDataLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(SystemResponseEnum.DICT_DATA_NAME_REPEAT);
        }
    }
}
