package com.cmvr.llm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.common.utils.http.CallAPIUtil;
import com.cmvr.llm.config.APIProperties;
import com.cmvr.llm.service.LLMTouchService;
import com.cmvr.llm.util.LargeModelFileUploadUtil;
import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.system.service.CarPathFinderService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class LLMTouchServiceImpl implements LLMTouchService {

    private final APIProperties apiProperties;
    private final CarPathFinderService carPathFinderService;

    @Override
    public String bgeVl(File image) {
        String response = CallAPIUtil.doPostFile(apiProperties.getBgeVl(), null, "image", image, null);
        JSONObject result = JSON.parseObject(response);
        return result.getString("uiName");
    }

    @Override
    public String getCoordinates(String iconImage, String iconDesc, String inputImage) {
        // 调用触控交互接口
        Map<String, String> params = new HashMap<>();
        params.put("icon_image", iconImage);
        params.put("icon_desc", iconDesc);
        params.put("input_image", inputImage);

        Map<String, String> headers = new HashMap<>();
        headers.put("Apikey", "d1ebtc5u6s5pkko77dkg");

        Map<String, String> body = new HashMap<>();
        body.put("AppKey", "d1ebtc5u6s5pkko77dkg");
        body.put("AppID", "d1ebtabnjkflk4gmhikg");
        body.put("InputData", JSON.toJSONString(params));
        body.put("UserID", "18888888888");

        String res1 = CallAPIUtil.doPostJson(apiProperties.getWorkFlowUrl(), headers, body);
        JSONObject resObject1 = JSON.parseObject(res1);
        if (resObject1.containsKey("runId")) {
            String processId = resObject1.getString("runId");
            return queryResultByRunId(processId);
        } else {
            throw new GlobalException("未获取到 runId，响应内容：" + res1);
        }
    }

    @Override
    public JSONObject touchCoordinates(File image, String targetUi, String manufacturer, String vehType) {
        JSONObject result = new JSONObject();
        result.put("isFinish", false);

        // 当前界面识别
        String currentUi = bgeVl(image);
        if (StrUtil.isEmpty(currentUi)) {
            throw new GlobalException("未获取到当前位置");
        }
        if (currentUi.equals("设置驾驶偏好")) {
            currentUi = "驾驶偏好";
        }

        // 已在目标界面：直接返回完成
        if (StrUtil.equals(currentUi, targetUi)) {
            result.put("isFinish", true);
            result.put("coordinates", "");
            return result;
        }

        // 计算从当前到目标的路径
        List<CarIcon> path = carPathFinderService.findPath(manufacturer, vehType, currentUi, targetUi);
        if (CollUtil.isEmpty(path)) {
            throw new GlobalException(StrUtil.format("未找到从 [{}] 到 [{}] 的路径", currentUi, targetUi));
        }

        // 下一步就是 path.get(0)
        CarIcon nextStepIcon = path.get(0);

        // 分别上传当前截图和图标图片获得可访问 URL
        String imageUrl;
        String iconImageUrl;
        String iconName = nextStepIcon.getIconName();
        try {
            // 上传截图
            byte[] imageBytes = FileUtil.readBytes(image);
            imageUrl = LargeModelFileUploadUtil.uploadFile(imageBytes);

            // 拼接图标路径，例如 icons/honda/sedan/空调控制.png
            String iconPath = StrUtil.format("icon/{}/{}/{}.png", manufacturer, vehType, iconName);

            // 从 resources 加载图标文件
            InputStream iconStream = this.getClass().getClassLoader().getResourceAsStream(iconPath);
            if (iconStream == null) {
                throw new GlobalException("未找到图标资源文件：" + iconPath);
            }

            // 上传图标
            byte[] iconBytes = IoUtil.readBytes(iconStream);
            // 设置的icon
//            iconImageUrl = "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload%2Ffull%2F8f%2F1a%2F1b0b791926b89d1c748c9cb1280bb3e4697543b3a715e692565107442c9c&IsAnonymous=true";
            iconImageUrl = LargeModelFileUploadUtil.uploadFile(iconBytes);
//            imageUrl = "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload%2Ffull%2F88%2F99%2Fe4452191c9706d107c17b27dc0a08e13a3a1a85a261eec802ae85c11f26c&IsAnonymous=true";
//            imageUrl = "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload/full/5d/a3/07244360c69636d5c146e5470d8d5ddf12ceed2643ffd892b7b7a5c4aaeb&IsAnonymous=true";
//            iconImageUrl =
//                    iconName.equals("驾驶偏好") ?
//                            "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload/full/a4/1b/6a7319709844c0f483a1d7adcfdbbff478ff5e34bed9ecff5d8fd407f3ac&IsAnonymous=true"
//                            : "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload%2Ffull%2Ff1%2Fb9%2F8fb5f96f0299ccef60511eb8f7cfdcec890e563bc8e00854e63484086953&IsAnonymous=true";
        } catch (Exception e) {
            throw new GlobalException("上传图标或截图失败：" + e.getMessage());
        }

        // 获取下一步点击坐标
        String coordinates;
        try {
            coordinates = getCoordinates(iconImageUrl, nextStepIcon.getIconDesc(), imageUrl);
        } catch (Exception e) {
            throw new GlobalException("获取点击坐标失败：" + e.getMessage());
        }

        // 7) 返回
        result.put("isFinish", path.size() == 1);
        result.put("coordinates", coordinates);

        return result;
    }

    private String queryResultByRunId(String processId) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Apikey", "d1ebtc5u6s5pkko77dkg");

        Map<String, String> body = new HashMap<>();
        body.put("AppKey", "d1ebtc5u6s5pkko77dkg");
        body.put("AppID", "d1ebtabnjkflk4gmhikg");
        body.put("RunID", processId);
        body.put("UserID", "18888888888");


        String responseBody;
        JSONObject endNode;
        int failCount = 0;
        int maxFail = 40;

        while (true) {
            responseBody = CallAPIUtil.doPostJson(apiProperties.getQueryResultUrl(), headers, body);
            JSONObject jsonObject = JSON.parseObject(responseBody);

            String status = jsonObject.getString("status");
            if ("success".equals(status)) {
                JSONObject nodes = jsonObject.getJSONObject("nodes");
                if (nodes == null) {
                    throw new GlobalException("响应中 nodes 为空：" + responseBody);
                }

                endNode = findEndNode(nodes);
                if (endNode != null) {
                    break;
                } else {
                    throw new GlobalException("未找到 nodeType=end 的节点：" + nodes);
                }
            } else if ("failed".equals(status)) {
                // 如果失败
                throw new GlobalException(responseBody);
            } else {
                // 处理其他状态码
                failCount++;
                if (failCount > maxFail) {
                    throw new GlobalException("达到最大重试次数，API状态仍未成功：" + status);
                }
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new GlobalException("轮询被中断");
            }
        }

        // 解析 output 内容并清洗
        JSONObject output = endNode.getJSONObject("output");
        String res = output.getString("content");
        if (StrUtil.isEmpty(res)) {
            throw new GlobalException("未找到坐标内容");
        }
        return res;
    }

    /**
     * 从 nodes 中提取 nodeType=end 的节点
     */
    private JSONObject findEndNode(JSONObject nodes) {
        for (Map.Entry<String, Object> entry : nodes.entrySet()) {
            JSONObject node = (JSONObject) entry.getValue();
            if ("end".equalsIgnoreCase(node.getString("nodeType"))) {
                return node;
            }
        }
        return null;
    }
}
