package com.sckw.system.dubbo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sckw.core.model.constant.Global;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.*;
import com.sckw.system.api.model.pojo.DeptInfoPojo;
import com.sckw.system.dao.SysDictDao;
import com.sckw.system.model.*;
import com.sckw.system.service.KwsUserService;
import com.sckw.system.service.SysAreaService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author czh
 * @desc 远程接口
 * @date 2023/6/12
 */
@DubboService(group = "design", version = "2.0.0")
@Service
public class RemoteSystemServiceImpl implements RemoteSystemService {

    @Autowired
    private SysDictDao sysDictDao;

    @Autowired
    private KwsUserService kwsUserService;

    @Autowired
    private RemoteBaseService remoteBaseService;

    @Autowired
    private SysAreaService sysAreaService;

    /**
     * @param keys type#value,type#value
     * @return Map<String, SysDictResDto>
     * @desc: 根据类型id查字典，先查redis，没查到查数据库，查出来了存redis
     * @author: czh
     * @date: 2023/7/5
     */
    @Override
    public Map<String, SysDictResDto> queryDictMapByTypeValues(String keys) {
        Map<String, SysDictResDto> map = new HashMap<>();
        String[] typeValueArr = keys.split(Global.COMMA);
        for (String typeValue : typeValueArr) {
            if (StringUtils.isNotBlank(typeValue)) {
                String[] split = typeValue.split(Global.POUND);
                SysDictResDto sysDictResDto = queryDictByTypeAndValue(split[0], split[1]);
                map.put(typeValue, sysDictResDto);
            }
        }

        return map;
    }

    /**
     * @param type 类型
     * @return Map<String, SysDictResDto>
     * @desc: 根据类型id查字典，先查redis，没查到查数据库，查出来了存redis
     * @author: czh
     * @date: 2023/7/5
     */
    @Override
    public Map<String, SysDictResDto> queryDictMapByType(String type) {
        List<SysDictResDto> sysDictResDtos = queryDictByType(type);
        if (CollectionUtils.isEmpty(sysDictResDtos)) {
            return new HashMap<>();
        }

        return sysDictResDtos.stream().collect(Collectors.toMap(SysDictResDto::getValue, v->v));
    }

    /**
     * @param type 类型
     * @return SysDictResDto
     * @desc: 根据类型id查字典，先查redis，没查到查数据库，查出来了存redis
     * @author: czh
     * @date: 2023/7/5
     */
    @Override
    public List<SysDictResDto> queryDictByType(String type) {
        String key = Global.REDIS_SYS_DICT_TYPE_PREFIX + type;
        String dictCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(dictCache)) {
            List<SysDict> sysDictList = sysDictDao.queryByType(type);
            if (CollectionUtils.isEmpty(sysDictList)) {
                return Collections.emptyList();
            }
            List<SysDictResDto> sysDictResDtos = BeanUtils.copyToList(sysDictList, SysDictResDto.class);
            RedissonUtils.putString(key, JSON.toJSONString(sysDictResDtos), Global.COMMON_EXPIRE);
            return sysDictResDtos;
        }

        return JSONObject.parseArray(dictCache, SysDictResDto.class);
    }

    /**
     * @param type 字典类型，value key
     * @return SysDictResDto
     * @desc: 根据字典类型和key查
     * @author: czh
     * @date: 2023/7/7
     */
    @Override
    public SysDictResDto queryDictByTypeAndValue(String type, String value) {
        String key = Global.REDIS_SYS_DICT_PREFIX + type + Global.POUND + value;
        String dictCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(dictCache)) {
            SysDict sysDict = sysDictDao.queryByTypeAndValue(type, value);
            if (Objects.isNull(sysDict)) {
                return null;
            }
            SysDictResDto sysDictResDto = new SysDictResDto();
            BeanUtils.copyProperties(sysDict, sysDictResDto);
            RedissonUtils.putString(key, JSON.toJSONString(sysDictResDto), Global.COMMON_EXPIRE);
            return sysDictResDto;
        }
        return JSONObject.parseObject(dictCache, SysDictResDto.class);
    }

    /**
     * @param type 字典类型
     * @return SysDictResDto
     * @desc: 根据字典类型和key查字典
     * @author: czh
     * @date: 2023/7/7
     */
    @Override
    public List<SysDictGroupResDto> queryDictGroupByType(String type) {
        List<SysDict> sysDicts = sysDictDao.queryByType(type);
        if (CollectionUtils.isEmpty(sysDicts)) {
            return Collections.emptyList();
        }

        //取最顶层去递归
        List<SysDictGroupResDto> list = new ArrayList<>();
        sysDicts = sysDicts.stream().filter(item -> item.getParentId().equals(String.valueOf(Global.NO))).toList();
        if (CollectionUtils.isEmpty(sysDicts)) {
            return Collections.emptyList();
        }

        sysDicts.forEach(item -> {
            SysDictGroupResDto sysDictGroupResDto = queryDictGroupByTypeAndValue(type, item.getValue());
            if (!Objects.isNull(sysDictGroupResDto)) {
                list.add(sysDictGroupResDto);
            }
        });

        return list;
    }

    @Override
    public List<SysDictResDto> queryDictBottom(String type, String value) {
        return null;
    }

    /**
     * @param type 字典类型，value key
     * @return SysDictGroupResDto
     * @desc: 根据字典类型和key查字典组
     * @author: czh
     * @date: 2023/7/7
     */
    @Override
    public SysDictGroupResDto queryDictGroupByTypeAndValue(String type, String value) {
        String key = Global.REDIS_SYS_DICT_GROUP_PREFIX + type + Global.POUND + value;
        String dictCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(dictCache)) {
            List<SysDict> list = sysDictDao.selectAll();
            if (CollectionUtils.isEmpty(list)) {
                return null;
            }
            Optional<SysDict> first = list.stream().filter(item -> item.getType().equals(type) && item.getValue().equals(value)).findFirst();
            if (first.isEmpty()) {
                return null;
            }

            SysDictGroupResDto sysDictGroupResDto = new SysDictGroupResDto();
            BeanUtils.copyProperties(first.get(), sysDictGroupResDto);
            sysDictGroupResDto.setChild(getChild(sysDictGroupResDto.getId(), list));
            RedissonUtils.putString(key, JSON.toJSONString(sysDictGroupResDto), Global.COMMON_EXPIRE);
            return sysDictGroupResDto;
        }
        return JSONObject.parseObject(dictCache, SysDictGroupResDto.class);
    }


    /**
     * @param entId 企业id
     * @return EntCacheResDto
     * @desc: 从缓存查企业信息
     * @author: czh
     * @date: 2023/7/7
     */
    @Override
    public EntCacheResDto queryEntCacheById(Long entId) {
        String key = Global.REDIS_ENTERPRISE_PREFIX + entId;
        String dictCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(dictCache)) {
            KwsEnterpriseResDto kwsEnterpriseResDto = remoteBaseService.queryEnterpriseById(entId);
            if (Objects.isNull(kwsEnterpriseResDto)) {
                return null;
            }

            EntCacheResDto entCacheResDto = new EntCacheResDto();
            BeanUtils.copyProperties(kwsEnterpriseResDto, entCacheResDto);
            entCacheResDto.setDeptInfo(remoteBaseService.queryDeftInfoByEntId(entId));
            entCacheResDto.setCertificateInfo(remoteBaseService.queryCertificateByEntId(entId));
            List<EntTypeResDto> entTypeResDtos = remoteBaseService.queryEntTypeById(entId);
            if (CollectionUtils.isNotEmpty(entTypeResDtos)) {
                entCacheResDto.setEntTypes(String.join(Global.COMMA, entTypeResDtos.stream().map(EntTypeResDto::getType).map(String::valueOf).distinct().toList()));
            }
            RedissonUtils.putString(key, JSON.toJSONString(entCacheResDto), Global.COMMON_EXPIRE);
            return entCacheResDto;
        }

        return JSONObject.parseObject(dictCache, EntCacheResDto.class);
    }

    /**
     * @param entName 企业名
     * @return EntCacheResDto
     * @desc: 从缓存查企业信息 模糊匹配
     * @author: czh
     * @date: 2023/7/7
     */
    @Override
    public List<EntCacheResDto> queryEntCacheByName(String entName) {
        List<KwsEnterprise> kwsEnterprises = remoteBaseService.queryEntByName(entName);
        if (CollectionUtils.isEmpty(kwsEnterprises)) {
            return Collections.emptyList();
        }

        List<EntCacheResDto> list = new ArrayList<>();
        for (KwsEnterprise kwsEnterprise : kwsEnterprises) {
            EntCacheResDto entCacheResDto = queryEntCacheById(kwsEnterprise.getId());
            if (!Objects.isNull(entCacheResDto)) {
                list.add(entCacheResDto);
            }
        }
        return list;
    }

    /**
     * @param entIdList 企业id集合
     * @return Map<Long, EntCacheResDto>
     * @desc: 查企业树
     * @author: czh
     * @date: 2023/7/17
     */
    @Override
    public Map<Long, EntCacheResDto> queryEntTreeByIds(List<Long> entIdList) {
        Map<Long, EntCacheResDto> result = new HashMap<>();
        for (Long entId : entIdList) {
            EntCacheResDto entCacheResDto = queryEntCacheById(entId);
            if (Objects.isNull(entCacheResDto)) {
                return new HashMap<>(1);
            }
            remoteBaseService.fillRelate(entCacheResDto);

            //有父企业
            Long parentId = entCacheResDto.getParentId();
            if (Objects.nonNull(parentId)) {
                EntCacheResDto parent = queryEntCacheById(parentId);
                parent.setChild(Collections.singletonList(entCacheResDto));
                result.put(entId, parent);
                continue;
            }

            //没有主体单位
            String entDeptIds = entCacheResDto.getEntDeptIds();
            if (StringUtils.isBlank(entDeptIds)) {
                result.put(entId, entCacheResDto);
                continue;
            }

            //有主体单位
            List<Long> entDeptIdList = Arrays.stream(entDeptIds.split(Global.COMMA)).map(Long::parseLong).toList();
            List<EntCacheResDto> child = queryEntCacheByIds(entDeptIdList);
            entCacheResDto.setChild(child);
            result.put(entId, entCacheResDto);
        }
        return result;
    }

    @Override
    public List<EntCacheResDto> queryEntCacheByIds(List<Long> entIds) {
        if (CollectionUtils.isEmpty(entIds)) {
            return Collections.emptyList();
        }
        List<EntCacheResDto> list = new ArrayList<>();
        entIds.stream().distinct().toList().forEach(entId -> {
            EntCacheResDto entCacheResDto = queryEntCacheById(entId);
            if (Objects.nonNull(entCacheResDto)) {
                list.add(entCacheResDto);
            }
        });
        return list;
    }

    @Override
    public Map<Long, List<EntCacheResDto>> queryEntDeptCacheByIds(List<Long> entIds) {
        List<KwsEntDept> kwsEntDepts = remoteBaseService.queryEntDeptCacheByIds(entIds);
        if (CollectionUtils.isEmpty(kwsEntDepts)) {
            return new HashMap<>(4);
        }

        Map<Long, List<KwsEntDept>> collect = kwsEntDepts.stream().collect(Collectors.groupingBy(KwsEntDept::getEntPid));
        Map<Long, List<EntCacheResDto>> map = new HashMap<>();
        for (Long key : collect.keySet()) {
            List<KwsEntDept> kwsEntDepts1 = collect.get(key);
            List<Long> entIdList = kwsEntDepts1.stream().map(KwsEntDept::getEntId).toList();
            List<EntCacheResDto> entCacheResDtos = queryEntCacheByIds(entIdList);
            map.put(key, entCacheResDtos);
        }
        return map;
    }

    @Override
    public Map<Long, EntCacheResDto> queryEntCacheMapByIds(List<Long> entIds) {
        List<EntCacheResDto> entCacheResDtos = queryEntCacheByIds(entIds);
        if (CollectionUtils.isEmpty(entCacheResDtos)) {
            return new HashMap<>();
        }
        return entCacheResDtos.stream().collect(Collectors.toMap(EntCacheResDto::getId, x -> x, (oldValue, newValue) -> newValue));
    }

    @Override
    public UserCacheResDto queryUserCacheById(Long userId) {
        String key = Global.REDIS_USER_PREFIX + userId;
        String dictCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(dictCache)) {
            KwsUser kwsUser = kwsUserService.selectByKey(userId);
            if (Objects.isNull(kwsUser)) {
                return null;
            }

            UserCacheResDto userCacheResDto = new UserCacheResDto();
            BeanUtils.copyProperties(kwsUser, userCacheResDto);
            userCacheResDto.setRoleInfo(remoteBaseService.queryRoleInfoByUserId(userId));

            List<KwsUserDeptResDto> kwsUserDeptResDtos = remoteBaseService.queryUserDeptByUserId(userId);
            if (CollectionUtils.isEmpty(kwsUserDeptResDtos)) {
                return userCacheResDto;
            }

            List<Long> deptIds = kwsUserDeptResDtos.stream().map(KwsUserDeptResDto::getDeptId).toList();
            List<KwsDeptResDto> kwsDeptResDtos = remoteBaseService.queryDeptByIds(deptIds);
            if (CollectionUtils.isEmpty(kwsDeptResDtos)) {
                return userCacheResDto;
            }

            Long entId = kwsDeptResDtos.get(0).getEntId();
            KwsEnterpriseResDto kwsEnterpriseResDto = remoteBaseService.queryEnterpriseById(entId);
            if (Objects.isNull(kwsEnterpriseResDto)) {
                return userCacheResDto;
            }

            EntCacheResDto entCacheResDto = new EntCacheResDto();
            BeanUtils.copyProperties(kwsEnterpriseResDto, entCacheResDto);
            entCacheResDto.setDeptInfo(BeanUtils.copyToList(kwsDeptResDtos, DeptInfoPojo.class));
            entCacheResDto.setCertificateInfo(remoteBaseService.queryCertificateByEntId(entId));
            userCacheResDto.setEntInfo(entCacheResDto);
            RedissonUtils.putString(key, JSON.toJSONString(userCacheResDto), Global.COMMON_EXPIRE);
            return userCacheResDto;
        }

        return JSONObject.parseObject(dictCache, UserCacheResDto.class);
    }

    @Override
    public List<UserCacheResDto> queryUserCacheByIds(List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return Collections.emptyList();
        }
        List<UserCacheResDto> list = new ArrayList<>();
        userIds.stream().distinct().toList().forEach(e -> {
            UserCacheResDto dto = queryUserCacheById(e);
            if (Objects.nonNull(dto)) {
                list.add(dto);
            }
        });
        return list;
    }

    @Override
    public Map<Long, UserCacheResDto> queryUserCacheMapByIds(List<Long> userIds) {
        List<UserCacheResDto> userCacheResDtos = queryUserCacheByIds(userIds);
        if (CollectionUtils.isEmpty(userCacheResDtos)) {
            return new HashMap<>();
        }
        return userCacheResDtos.stream().collect(Collectors.toMap(UserCacheResDto::getId, x -> x, (oldValue, newValue) -> newValue));
    }

    @Override
    public SysAreaCacheResDto queryAreaCacheById(Integer code) {
        String key = Global.REDIS_AREA_PREFIX + code;
        String areaCache = RedissonUtils.getString(key);
        //从redis查，查不到从数据库查，并写入redis
        if (StringUtils.isBlank(areaCache)) {
            SysArea sysArea = sysAreaService.selectById(code);
            if (Objects.isNull(sysArea)) {
                return new SysAreaCacheResDto();
            }

            SysAreaCacheResDto sysAreaCacheResDto = BeanUtils.copyProperties(sysArea, SysAreaCacheResDto.class);
            RedissonUtils.putString(key, JSON.toJSONString(sysAreaCacheResDto), Global.COMMON_EXPIRE);
            return sysAreaCacheResDto;
        }
        return JSONObject.parseObject(areaCache, SysAreaCacheResDto.class);
    }

    @Override
    public UserCacheResDto queryManagerInfoByEntId(Long entId) {
        KwsEnterpriseResDto kwsEnterpriseResDto = remoteBaseService.queryEnterpriseById(entId);
        if (Objects.isNull(kwsEnterpriseResDto) || Objects.isNull(kwsEnterpriseResDto.getManager())) {
            return null;
        }

        if (Objects.isNull(kwsEnterpriseResDto.getManager())) {
            return null;
        }

        return queryUserCacheById(kwsEnterpriseResDto.getManager());
    }

    /**
     * @param id 父id，需要遍历的list
     * @return SysDictGroupResDto
     * @desc: 构建字典组
     * @author: czh
     * @date: 2023/7/7
     */
    private List<SysDictGroupResDto> getChild(Long id, List<SysDict> list) {
        List<SysDictGroupResDto> child = new ArrayList<>();
        for (SysDict sysDict : list) {
            if (sysDict.getParentId().equals(String.valueOf(id))) {
                SysDictGroupResDto sysDictGroupResDto = new SysDictGroupResDto();
                BeanUtils.copyProperties(sysDict, sysDictGroupResDto);
                child.add(sysDictGroupResDto);
            }
        }

        if (!CollectionUtils.isEmpty(child)) {
            for (SysDictGroupResDto sysDictGroupResDto : child) {
                sysDictGroupResDto.setChild(getChild(sysDictGroupResDto.getId(), list));
            }
        }
        return child;
    }

}
