package com.hdkj.lt.si.service.svg.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.hdkj.lt.base.constants.ErrorLogConstant;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.exception.ExceptionCast;
import com.hdkj.lt.core.log.exception.ExceptionErrorLogCast;
import com.hdkj.lt.core.log.model.param.ErrorLogParam;
import com.hdkj.lt.modle.dto.svg.CityFeederInfo;
import com.hdkj.lt.si.dao.CityFeederTopoMapper;
import com.hdkj.lt.si.service.simulation.TyptResponseEntity;
import com.hdkj.lt.si.service.svg.ICityFeederTopoService;
import com.hdkj.lt.utils.cache.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @Description:
 * @Author: LiuAini
 * @Date: 2025/7/11 17:47
 * @Version: v1.0
 */
@Service
@Slf4j
public class CityFeederTopoServiceImpl implements ICityFeederTopoService {

    @Autowired
    @Qualifier("simpleLongTimeRestTemplate")
    private RestTemplate restTemplate;

    @Value("${remote.topo.request-uri}")
    private String requestUri;

    @Resource
    private CityFeederTopoMapper cityFeederTopoMapper;

    @Resource
    private RedisUtil redisUtils;

    @Override
    public Boolean doCityFeederTopo(List<String> list) {
        try {
            HttpEntity<Object> httpEntity = this.createHttpEntity(list);
            log.info("调用解析地市线路拓扑数据开始：入参：{}", JSON.toJSONString(httpEntity));
            ResponseEntity<TyptResponseEntity> exchange = restTemplate.exchange(requestUri, HttpMethod.POST, httpEntity, TyptResponseEntity.class);
            TyptResponseEntity restRespEntity = exchange.getBody();
            if (!HttpStatus.OK.equals(exchange.getStatusCode()) || Objects.isNull(restRespEntity)) {
                String messagePattern = String.format("call failed, methodUrl: %s,\n requestBody: %s,\n restRespEntity: %s", requestUri, JSON.toJSONString(list), JSON.toJSONString(restRespEntity));
                StringBuilder errorMsg = new StringBuilder(messagePattern);
                Optional.ofNullable(restRespEntity).ifPresent(e -> errorMsg.append(",\n errorMsg：").append(e.getMsg()));
                ExceptionCast.cast(errorMsg.toString());
            }
            log.info("call successful, methodUrl: {},\n requestBody: {},\n callRespEntity: {}", requestUri, JSON.toJSONString(list), JSON.toJSONString(restRespEntity));
//            Object data = remoteCallService.call(requestUrl, HttpMethod.POST, list, Object.class);
            return JSON.parseObject(JSON.toJSONString(restRespEntity), Boolean.class);
        } catch (Exception e) {
            e.printStackTrace();
            dealCatchErrorLog(list);
//            ExceptionCast.cast("调用拓扑解析接口失败");
        } finally {
            redisUtils.del(RedisKeyConstants.ERROR_CACHE_KEY_TOPO_DATA);
        }
        return Boolean.FALSE;
    }
    private <B> HttpEntity<B> createHttpEntity(B body) {
        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        headers.set(HttpHeaders.ACCEPT_CHARSET, Charsets.UTF_8.toString());
        return new HttpEntity<>(body, headers);
    }

    @Override
    public List<String> getCityFeederSvg() {
        String topoVersion = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd");
        //根据版本获取线路id
        List<CityFeederInfo> lineFileList = this.getAllLineFileByVersion(topoVersion,null);
        return lineFileList.stream().map(CityFeederInfo::getCity).distinct().collect(Collectors.toList());

    }

    @Override
    public Boolean dealCityFeederTopo(List<String> cityIds) {
        if(CollectionUtils.isEmpty(cityIds)){
            cityIds = getCityFeederSvg();
        }
        if(CollectionUtils.size(cityIds)>0){
            return doCityFeederTopo(cityIds);
        }
        return false;
    }

    private List<CityFeederInfo> getAllLineFileByVersion(String topoVersion,List<String> lineFileList){
        return cityFeederTopoMapper.getAllLineFileByVersion(topoVersion,lineFileList);

    }

    private void dealSaveErrorLog(ErrorLogParam errorLogParam){
        errorLogParam.setEventType(ErrorLogConstant.EventType.TOPO_DATA)
                .setErrorLevel(ErrorLogConstant.ErrorLevel.WARNING)
                .setStage(ErrorLogConstant.Stage.ANALYSIS_TOPO)
                .setRelatedCategory("fhzg_dist_mapping_file")
                .setSourceSystem(ErrorLogConstant.SourceSystem.FHZG)
                .setOperationStep("图模获取");
    }
    private void dealCatchErrorLog(List<String> list){
        Object o = redisUtils.get(RedisKeyConstants.ERROR_CACHE_KEY_TOPO_DATA);
        ErrorLogParam errorLogParam = JSON.parseObject(JSON.toJSONString(o), ErrorLogParam.class);
        if(Objects.isNull(errorLogParam)){
            String cityId = list.get(0);
            errorLogParam = new ErrorLogParam();
            errorLogParam.setEventId(LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd"))
                    .setEventType(ErrorLogConstant.EventType.TOPO_DATA)
                    .setErrorLevel(ErrorLogConstant.ErrorLevel.FATAL)
                    .setStage(ErrorLogConstant.Stage.ANALYSIS_TOPO)
                    .setRelatedCategory("fhzg_dist_mapping_file")
                    .setSourceSystem(ErrorLogConstant.SourceSystem.FHZG)
                    .setOperationStep("图模解析").setErrorCategory("服务调用异常")
                    .setErrorTime(LocalDateTime.now())
                    .setRelatedId(cityId).setDetails("调用拓扑解析接口失败");
        }
        ExceptionErrorLogCast.cast(errorLogParam);
    }
}
