package com.infoepoch.pms.agent.domain.itworkbench.remote;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.infoepoch.pms.agent.common.utils.LogHelper;
import com.infoepoch.pms.agent.config.JsonUtils;
import com.infoepoch.pms.agent.domain.itworkbench.model.QueryDto;
import com.infoepoch.pms.agent.domain.itworkbench.model.department.DepartmentWork;
import com.infoepoch.pms.agent.domain.itworkbench.model.kpi.AnnualKpi;
import com.infoepoch.pms.agent.domain.itworkbench.model.kpi.AnnualKpiDto;
import com.infoepoch.pms.agent.domain.itworkbench.model.minutes.DepartmentMinutes;
import com.infoepoch.pms.agent.domain.itworkbench.model.minutes.DepartmentMinutesDto;
import com.infoepoch.pms.agent.domain.itworkbench.model.department.DepartmentWorkDto;
import com.infoepoch.pms.agent.observability.ai.ObservedRestClientFactory;
import com.infoepoch.pms.agent.properties.ITProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClient;
import org.springframework.web.util.UriBuilder;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WorkbenchRemoteService {

    @Autowired
    ObjectMapper objectMapper;
    private static final int SUCCESS_CODE = 1;

    private final RestClient restClient;

    ITProperties properties;


    public WorkbenchRemoteService(ITProperties properties,ObservedRestClientFactory observedRestClientFactory) {
        this.properties = properties;
        this.restClient = observedRestClientFactory.create(
                properties.getBaseUrl(),
                observedRestClientFactory.defaultRequestFactory(),
                "itBusinessProvider"
        );
    }

    // 调用 重点工作接口
    public List<DepartmentWork> queryWork(DepartmentWorkDto dto) {
        List<DepartmentWork> departmentWorkList = new ArrayList<>();
        try {
            String url = properties.getWorkPath();
            JsonNode root = postForJson(url, null, dto);
            JsonNode dataNode = extractDataNode(root, url, false);
            JsonNode data = dataNode.get("entityList");
            if (data == null || data.isNull() || !data.isArray()) {
                LogHelper.info(this, "业务接口未返回数据: " + url);
                return List.of();
            } else {
                for (JsonNode item : data) {
                    if (item.isObject()) {
                        DepartmentWork departmentWork = objectMapper.convertValue(item, DepartmentWork.class);
                        departmentWorkList.add(departmentWork);
                    }
                }
                return departmentWorkList;
            }
        } catch (Exception e) {
            return null;
        }
    }

    // 调用 KPI接口
    public List<AnnualKpi> queryKpi(AnnualKpiDto dto) {
        List<AnnualKpi> annualKpiList = new ArrayList<>();
        try {
            String url = properties.getKpiPath();
            JsonNode root = postForJson(url, null , dto);
            JsonNode dataNode = extractDataNode(root, url, false);
            JsonNode data = dataNode.get("entityList");
            if (data == null || data.isNull() || !data.isArray()) {
                LogHelper.info(this, "业务接口未返回数据: " + url);
                return List.of();
            } else {
                for (JsonNode item : data) {
                    if (item.isObject()) {
                        AnnualKpi annualKpi = objectMapper.convertValue(item, AnnualKpi.class);
                        annualKpiList.add(annualKpi);
                    }
                }
                return annualKpiList;
            }
        } catch (Exception e) {
            return null;
        }
    }

    // 调用 会议纪要接口
    public List<DepartmentMinutes> queryMinutes(DepartmentMinutesDto dto) {
       List<DepartmentMinutes> minutesList = new ArrayList<>();
        try {
            String url =  properties.getMinutesPath();
            LogHelper.info(this, "业务接口地址: " + url);
            JsonNode root = postForJson(url, null, dto);
            JsonNode dataNode = extractDataNode(root, url, false);
            JsonNode data = dataNode.get("entityList");
            if (data == null || data.isNull() || !data.isArray()) {
                LogHelper.info(this, "业务接口未返回数据: " + url);
                return List.of();
            } else {
                for (JsonNode item : data) {
                    if (item.isObject()) {
                        DepartmentMinutes departmentMinutes = objectMapper.convertValue(item, DepartmentMinutes.class);
                        minutesList.add(departmentMinutes);
                    }
                }
                return minutesList;
            }
        } catch (Exception e) {
            return null;
        }
    }



    /**
     * 执行 HTTP POST 请求并将返回值解析为 JsonNode。
     */
    private JsonNode postForJson(String path, Map<String, Object> queryParams, Object requestBody) {
        RestClient.RequestBodySpec spec = restClient.post()
                .uri(uriBuilder -> buildUri(uriBuilder, path, queryParams))
                .contentType(MediaType.APPLICATION_JSON);
        if (requestBody != null) {
            spec.body(requestBody);
        }
        String response = spec.retrieve().body(String.class);
        if (!StringUtils.hasText(response)) {
            throw new IllegalStateException("业务接口返回为空: " + path);
        }
        JsonNode jsonNode = JsonUtils.jsonToJsonNode(response);
        if (jsonNode == null) {
            throw new IllegalStateException("业务接口返回不是合法JSON: " + path);
        }
        return jsonNode;
    }


    /**
     * 从统一 AgentResponse 结构中读取 data 节点，并校验业务响应码。
     */
    private JsonNode extractDataNode(JsonNode root, String path, boolean requireData) {
        if (root == null || !root.isObject()) {
            throw new IllegalStateException("业务接口返回结构不正确: " + path);
        }
        int code = root.path("code").asInt();
        String msg = root.path("msg").asText();
        if (code != SUCCESS_CODE) {
            throw new IllegalStateException(StringUtils.hasText(msg) ? msg : "业务接口调用失败: " + path);
        }
        JsonNode dataNode = root.get("data");
        if (requireData && (dataNode == null || dataNode.isNull())) {
            throw new IllegalStateException(StringUtils.hasText(msg) ? msg : "业务接口未返回数据: " + path);
        }
        return dataNode;
    }

    private URI buildUri(UriBuilder uriBuilder, String path, Map<String, Object> params) {
        uriBuilder.path(path);
        if(params != null){
            params.forEach((key, value) -> {
                if (value != null) {
                    uriBuilder.queryParam(key, value);
                }
            });
        }
        return uriBuilder.build();
    }

    public JsonNode queryValidAuthority(QueryDto dto) {
        try {
            String url =  properties.getAuthorityPath();
            LogHelper.info(this, "业务接口地址: " + url);
            JsonNode root = postForJson(url, null, dto);
            if (!root.isObject()) {
                throw new IllegalStateException("业务接口返回结构不正确: " + url);
            }
            return root;
        } catch (Exception e) {
            return null;
        }
    }
}