package com.tuoheng.third.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.common.CommonConfig;
import com.tuoheng.common.ServiceException;
import com.tuoheng.constant.CommonConstant;
import com.tuoheng.constant.DictConstant;
import com.tuoheng.constant.DspConstant;
import com.tuoheng.enums.MarkTypeEnum;
import com.tuoheng.mapper.DictDataMapper;
import com.tuoheng.mapper.PlatformMapper;
import com.tuoheng.model.dto.ClientRoleListDto;
import com.tuoheng.model.dto.LoginUser;
import com.tuoheng.model.dto.Platform;
import com.tuoheng.model.dto.RoleDto;
import com.tuoheng.model.entity.DictData;
import com.tuoheng.model.param.ClientRoleDto;
import com.tuoheng.third.request.ModelInfoDao;
import com.tuoheng.third.request.ThirdRequest;
import com.tuoheng.third.service.ThirdService;
import com.tuoheng.third.vo.*;
import com.tuoheng.until.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

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

/**
 * @Author xiaoying
 * @Date 2023/3/8 9:01
 */
@Service
@Slf4j
public class ThirdServiceImpl implements ThirdService {

    @Autowired
    private PlatformMapper platformMapper;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DictDataMapper dictDataMapper;

    /**
     * dsp -获取算法实例
     *
     * @return
     */
    @Override
    public JsonResult findExample() {

        String url = CommonConfig.dspURL + DspConstant.FIND_EXAMPLE;

        ParameterizedTypeReference<JsonResult<List<IndustryVo>>> parameterizedTypeReference =
                new ParameterizedTypeReference<JsonResult<List<IndustryVo>>>() {
                };
        ResponseEntity<JsonResult<List<IndustryVo>>> response;
        try {
            log.info("url:{}", url);
            response = restTemplate.exchange(url, HttpMethod.GET, null, parameterizedTypeReference);
        } catch (Exception e) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "请求发送内部出现异常!");
        }
        if (response == null || !response.hasBody() || response.getBody().getCode() != JsonResult.SUCCESS) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "dsp获取服务实例异常");
        }

        List<IndustryVo> list = response.getBody().getData();
        List<ServiceExampleVo> serviceInstListVoList = new ArrayList<>();
        for (IndustryVo industryVo : list) {
            List<ServiceExampleVo> serviceExampleVos = industryVo.getServiceInstListVoList();
            if (ObjectUtil.isNotEmpty(serviceExampleVos)) {
                serviceInstListVoList.addAll(serviceExampleVos);
            }
        }

        return JsonResult.success(serviceInstListVoList);
    }

    /**
     * 根据serviceIds获取对面模型集合相关
     *
     * @return
     */
    @Override
    public List<ClientRoleDto> getModelList(List<ClientRoleDto> list) {


        for (ClientRoleDto clientRoleDto : list) {
            if (ObjectUtil.isNotEmpty(clientRoleDto.getServiceId())) {

                List<String> collect = Arrays.stream(clientRoleDto.getServiceId().split(",")).collect(Collectors.toList());
                String param = collect.toString().replace("[", "").replace("]", "");
                String url = CommonConfig.dspURL + DspConstant.FIND_MODELIST + "?serviceIds=" + param;

                ParameterizedTypeReference<JsonResult<List<ModelInfoDao>>> parameterizedTypeReference =
                        new ParameterizedTypeReference<JsonResult<List<ModelInfoDao>>>() {
                        };
                ResponseEntity<JsonResult<List<ModelInfoDao>>> response;
                try {
                    log.info("url:{}", url);
                    response = restTemplate.exchange(url, HttpMethod.GET, null, parameterizedTypeReference);
                } catch (Exception e) {
                    throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "请求发送内部出现异常!");
                }
                if (null == response || !response.hasBody() || response.getBody().getCode() != JsonResult.SUCCESS) {
                    throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "dsp获取服务实例异常");
                }
                List<ModelInfoDao> modelInfoDaos = response.getBody().getData();
                clientRoleDto.setModelInfoDaos(modelInfoDaos);
            }
        }
        return list;
    }

    /**
     * 查询对应业务平台的所有角色
     *
     * @param clientId  平台标识
     * @param loginUser
     * @return
     */
    @Override
    public JsonResult getRoleList(String clientId, LoginUser loginUser) {

        if (ObjectUtil.isEmpty(clientId)) {
            return JsonResult.error("clientId不能为空");
        }
        List<ClientRoleListDto> clientRoleListDtos = new ArrayList<>();

        if (clientId.contains(CommonConstant.COMMA)) {
            String[] clientIds = clientId.split(CommonConstant.COMMA);
            for (String id : clientIds) {
                ClientRoleListDto dto = getRoleListByClinetId(id, loginUser);
                clientRoleListDtos.add(dto);
            }
        } else {
            ClientRoleListDto dto = getRoleListByClinetId(clientId, loginUser);
            clientRoleListDtos.add(dto);
        }
        return JsonResult.success(clientRoleListDtos);
    }

    /**
     * 查询对应业务平台角色对应的菜单
     *
     * @param request   请求参数
     * @param loginUser
     * @return
     */
    @Override
    public JsonResult getMenuList(ThirdRequest request, LoginUser loginUser) {

        if (ObjectUtil.isEmpty(request.getClientId()) || ObjectUtil.isNull(request.getRoleId())) {
            return JsonResult.error("请求参数有误!");

        }
        RoleMenuListVo vo = getRoleMenuVoByThirdRequest(request, loginUser);

        return JsonResult.success(vo);
    }

    /**
     * 获取对应业务平台的角色对应的菜单列表
     *
     * @param request
     * @param loginUser
     * @return
     */
    private RoleMenuListVo getRoleMenuVoByThirdRequest(ThirdRequest request, LoginUser loginUser) {

        Platform platform = platformMapper.selectOne(Wrappers.<Platform>lambdaQuery()
                .eq(Platform::getPlatformCode, request.getClientId())
                .eq(Platform::getMark, 1));
        if (ObjectUtil.isNull(platform)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "该业务平台不存在");
        }
        RoleMenuVo vo = new RoleMenuVo();
        RoleMenuListVo roleMenuListVo = new RoleMenuListVo();
        vo.setRoleId(request.getRoleId());
        String url = "";
        DictData dictData = getDictData(request.getClientId(), DictConstant.GET_MENU);
        if (ObjectUtil.isNull(dictData)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "该业务平台对应字典表数据不存在");
        }
        url = String.format(Locale.ENGLISH, "%s%s", platform.getPlatformUrl(), dictData.getValue());
        ParameterizedTypeReference<JsonResult<RoleMenuVo>> parameterizedTypeReference =
                new ParameterizedTypeReference<JsonResult<RoleMenuVo>>() {
                };
        ResponseEntity<JsonResult<RoleMenuVo>> response;
        org.springframework.http.HttpHeaders resultRequestHeader = new HttpHeaders();
        resultRequestHeader.add("Authorization", "Bearer " + loginUser.getThToken());
        HttpEntity httpEntity = new HttpEntity(resultRequestHeader);
        try {
            log.info("url:{}", url);
            response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, parameterizedTypeReference, request.getRoleId());
        } catch (Exception e) {
            log.error("对应平台标识:{}", platform.getPlatformName());
            log.info(e.getMessage());
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取菜单列表失败!");
        }
        if (response == null || !response.hasBody() || response.getBody().getCode() != JsonResult.SUCCESS) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取菜单表响应失败!");
        }
        RoleMenuVo menuVo = response.getBody().getData();
        Map<String, List<MenuVo>> collect = menuVo.getOpMenusList().parallelStream().collect(Collectors.groupingBy(MenuVo::getClientId));
        Set<Map.Entry<String, List<MenuVo>>> entries = collect.entrySet();
        //区分小程序菜单及pc菜单
        for (Map.Entry<String, List<MenuVo>> entry : entries) {
            if (entry.getKey().contains("mp")) {
                roleMenuListVo.setMpMenusList(entry.getValue());
            } else if (entry.getKey().contains("admin")) {
                roleMenuListVo.setAdminMenusList(entry.getValue());
            }
        }
        return roleMenuListVo;
    }

    /**
     * 访问对应系统获取对应业务平台可关联的角色
     *
     * @param clientId
     * @param loginUser
     * @return
     */
    private ClientRoleListDto getRoleListByClinetId(String clientId, LoginUser loginUser) {

        Platform platform = platformMapper.selectOne(Wrappers.<Platform>lambdaQuery()
                .eq(Platform::getPlatformCode, clientId)
                .eq(Platform::getMark, 1));
        if (ObjectUtil.isNull(platform)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "该业务平台不存在");
        }
        ClientRoleListDto clientRoleListDto = new ClientRoleListDto();
        clientRoleListDto.setPlatformName(platform.getPlatformName());
        clientRoleListDto.setClientId(platform.getPlatformCode());
        String url = platform.getPlatformUrl();
        //根据不同业务平台进行动态匹配  ->并修改对应标识权限
        DictData dictData = getDictData(clientId, DictConstant.GET_ROLE);
        if (ObjectUtil.isNull(dictData)) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "该业务平台对应字典表数据不存在");
        }
        url = url + dictData.getValue();
        ParameterizedTypeReference<JsonResult<List<RoleDto>>> parameterizedTypeReference =
                new ParameterizedTypeReference<JsonResult<List<RoleDto>>>() {
                };
        ResponseEntity<JsonResult<List<RoleDto>>> response;
        org.springframework.http.HttpHeaders resultRequestHeader = new HttpHeaders();
        resultRequestHeader.add("Authorization", "Bearer " + loginUser.getThToken());
        HttpEntity httpEntity = new HttpEntity(resultRequestHeader);
        try {
            log.info("url:{}", url);
            response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, parameterizedTypeReference);
        } catch (Exception e) {
            log.error("对应平台标识:{}", platform.getPlatformName());
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取角色列表失败!");
        }
        if (response == null || !response.hasBody() || response.getBody().getCode() != JsonResult.SUCCESS) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "获取角色列表响应失败!");
        }
        List<RoleDto> roleDtos = response.getBody().getData();
        clientRoleListDto.setRoleDtoList(roleDtos);
        return clientRoleListDto;

    }

    /**
     * 获取字典表数据
     *
     * @param type
     * @param dictCode
     * @return
     */
    private DictData getDictData(String type, String dictCode) {
        DictData dictData = dictDataMapper.selectOne(Wrappers.<DictData>lambdaQuery()
                .eq(DictData::getDictType, type)
                .eq(DictData::getCode, dictCode)
                .eq(DictData::getMark, MarkTypeEnum.VALID.getCode()));
        return dictData;
    }
}
