package com.njzscloud.supervisory.doubao.sevice.impl;

import com.njzscloud.supervisory.doubao.config.DouBaoProperties;
import com.njzscloud.supervisory.doubao.param.GarbageAnalysisParam;
import com.njzscloud.supervisory.doubao.result.GarbageAnalysisResult;
import com.njzscloud.supervisory.doubao.sevice.DouBaoService;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionContentPart;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 火山引擎豆包服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DouBaoServiceImpl implements DouBaoService {

    private final ArkService arkService;
    private final DouBaoProperties douBaoProperties;

    /**
     * 垃圾分析 - 分析多张图片中的垃圾类型、占比和重量
     *
     * @param param 垃圾分析请求参数，包含多张图片URL
     * @return 垃圾分析结果，包含垃圾类型、判断依据、占比、重量等信息
     */
    @Override
    public GarbageAnalysisResult analyzeGarbage(GarbageAnalysisParam param) {
        try {
            log.info("开始调用火山引擎豆包API进行垃圾分析，订单号：{}，图片数量：{}",
                    param != null ? param.getOrderSn() : "未知",
                    param != null && param.getImageUrls() != null ? param.getImageUrls().size() : 0);

            // 参数校验
            if (param == null || CollectionUtils.isEmpty(param.getImageUrls())) {
                throw new IllegalArgumentException("垃圾分析参数不能为空，且必须包含至少一张图片URL");
            }

            // 构建消息列表
            final List<ChatMessage> messages = new ArrayList<>();
            final List<ChatCompletionContentPart> multiParts = new ArrayList<>();

            // 添加所有图片URL
            for (String imageUrl : param.getImageUrls()) {
                if (StringUtils.hasText(imageUrl)) {
                    multiParts.add(ChatCompletionContentPart.builder()
                            .type("image_url")
                            .imageUrl(new ChatCompletionContentPart.ChatCompletionContentPartImageURL(imageUrl))
                            .build());
                }
            }

            // 添加文本提示词，要求返回JSON格式
            String textPrompt = buildGarbageAnalysisPrompt(param);
            multiParts.add(ChatCompletionContentPart.builder()
                    .type("text")
                    .text(textPrompt)
                    .build());

            // 构建用户消息
            final ChatMessage userMessage = ChatMessage.builder()
                    .role(ChatMessageRole.USER)
                    .multiContent(multiParts)
                    .build();
            messages.add(userMessage);

            // 构建请求
            ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                    .model(douBaoProperties.getModel())
                    .messages(messages)
                    .build();

            // 调用API并获取响应
            String response = arkService.createChatCompletion(chatCompletionRequest)
                    .getChoices()
                    .stream()
                    .map(choice -> String.valueOf(choice.getMessage().getContent()))
                    .collect(Collectors.joining("\n"));

            log.info("火山引擎豆包API调用成功，原始响应内容：{}", response);

            // 解析响应并转换为结果对象
            GarbageAnalysisResult result = parseGarbageAnalysisResponse(response);
            result.setRawResponse(response);
            result.setAnalysisTime(System.currentTimeMillis());

            log.info("垃圾分析完成，车棚状态：{}，垃圾类型：{}，轻物质占比：{}%，重物质占比：{}%",
                    result.getIsShedOpened() != null && result.getIsShedOpened() ? "已打开" : "未打开",
                    result.getGarbageType(),
                    result.getLightMaterialPercentage(),
                    result.getHeavyMaterialPercentage());

            return result;

        } catch (Exception e) {
            log.error("调用火山引擎豆包API进行垃圾分析失败，订单号：{}",
                    param != null ? param.getOrderSn() : "未知", e);
            throw new RuntimeException("垃圾分析失败：" + e.getMessage(), e);
        }
    }

    /**
     * 构建垃圾分析提示词
     * 要求AI返回指定格式的文本
     */
    private String buildGarbageAnalysisPrompt(GarbageAnalysisParam param) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("请仔细分析这些图片中的垃圾内容。\n\n");

        // 添加订单信息（如果有）
        if (StringUtils.hasText(param.getOrderSn())) {
            prompt.append("订单号：").append(param.getOrderSn()).append("\n");
        }
        if (StringUtils.hasText(param.getRemark())) {
            prompt.append("备注：").append(param.getRemark()).append("\n");
        }

        prompt.append("\n请按照以下要求进行分析：\n");
        prompt.append("1. 首先判断图片中是否有垃圾运输车辆：\n");
        prompt.append("   - 如果图片中没有车辆（直接是垃圾堆、垃圾场等场景），请直接跳到第3步分析垃圾内容\n");
        prompt.append("   - 如果图片中有车辆，请继续第2步判断车棚状态\n");
        prompt.append("2. 如果图片中有车辆，判断车棚是否完全打开：\n");
        prompt.append("   - 如果车棚没有完全打开，无法看到车厢内的垃圾内容，直接回答：未打开车棚\n");
        prompt.append("   - 如果车棚完全打开，可以看到车厢内的垃圾，请继续第3步分析\n");
        prompt.append("3. 分析垃圾内容（适用于：无车辆的场景，或有车辆且车棚已打开的场景）：\n");
        prompt.append("   - 识别垃圾中包含哪几种物品（如果有多辆车，只分析画面中间的车辆或主要垃圾堆）\n");
        prompt.append("   - 说明哪种物品占比最多\n");
        prompt.append("   - 给出轻物质和重物质的大概占比（使用百分比数值，0-100）\n");
        prompt.append("   - 判断垃圾类型：拆除垃圾、装修垃圾或抛货\n");
        prompt.append("   - 说明判断垃圾类型的原因\n\n");

        prompt.append("请严格按照以下格式返回结果，不要添加任何其他文字说明：\n");
        prompt.append("如果图片中有车辆且车棚未打开，直接回答：未打开车棚\n");
        prompt.append("如果图片中没有车辆，或者有车辆且车棚已打开，按照以下格式回答：\n");
        prompt.append("明细:物品1(数量描述),物品2(数量描述);轻物质:x%;重物质:x%;垃圾类型:x;判断依据:x\n\n");
        prompt.append("格式说明：\n");
        prompt.append("- 明细：列出垃圾中包含的所有物品，用逗号分隔，每个物品后标注数量（多、少、较多、较少等）\n");
        prompt.append("- 轻物质：轻物质的占比百分比（0-100）\n");
        prompt.append("- 重物质：重物质的占比百分比（0-100），轻物质和重物质占比之和应为100%\n");
        prompt.append("- 垃圾类型：拆除垃圾、装修垃圾或抛货\n");
        prompt.append("- 判断依据：详细说明为什么判断为该垃圾类型\n\n");
        prompt.append("示例：\n");
        prompt.append("明细:石块(多);轻物质:0%;重物质:100%;垃圾类型:拆除垃圾;判断依据:主要为石块,这类垃圾多来自建筑物拆除等工程\n");
        prompt.append("明细:白色板材(多),白色泡沫(少),木棍(少);轻物质:90%;重物质:10%;垃圾类型:装修垃圾;判断依据:主要是白色板材、泡沫等装修常见废弃物\n");
        prompt.append("明细:纸箱(多),塑料瓶(少),泡沫箱(少);轻物质:95%;重物质:5%;垃圾类型:抛货;判断依据:主要是轻质包装材料,属于抛货类垃圾\n\n");
        prompt.append("注意：必须严格按照上述格式返回，不要添加任何其他文字说明。");

        return prompt.toString();
    }

    /**
     * 解析垃圾分析响应
     * 从AI响应中提取信息并转换为结果对象
     * 格式：明细:xx(x),xx(x);轻物质:x%;重物质:x%;垃圾类型:x;判断依据:x
     * 或者：未打开车棚
     */
    private GarbageAnalysisResult parseGarbageAnalysisResponse(String response) {
        if (!StringUtils.hasText(response)) {
            throw new RuntimeException("AI响应为空，无法解析");
        }

        try {
            GarbageAnalysisResult result = new GarbageAnalysisResult();
            String trimmed = response.trim();

            // 检查是否是"未打开车棚"的情况
            if (trimmed.contains("未打开车棚")) {
                result.setIsShedOpened(false);
                result.setDetails("未打开车棚");
                result.setLightMaterialPercentage(BigDecimal.ZERO);
                result.setHeavyMaterialPercentage(BigDecimal.ZERO);
                result.setGarbageType("无");
                result.setJudgmentBasis("车棚未完全打开，无法进行分析");
                return result;
            }

            // 车棚已打开，解析详细格式
            result.setIsShedOpened(true);

            // 提取明细
            Pattern detailsPattern = Pattern.compile("明细[:：]([^;]+)");
            Matcher detailsMatcher = detailsPattern.matcher(trimmed);
            if (detailsMatcher.find()) {
                result.setDetails(detailsMatcher.group(1).trim());
            }

            // 提取轻物质占比
            Pattern lightPattern = Pattern.compile("轻物质[:：](\\d+(?:\\.\\d+)?)%");
            Matcher lightMatcher = lightPattern.matcher(trimmed);
            if (lightMatcher.find()) {
                result.setLightMaterialPercentage(new BigDecimal(lightMatcher.group(1)));
            }

            // 提取重物质占比
            Pattern heavyPattern = Pattern.compile("重物质[:：](\\d+(?:\\.\\d+)?)%");
            Matcher heavyMatcher = heavyPattern.matcher(trimmed);
            if (heavyMatcher.find()) {
                result.setHeavyMaterialPercentage(new BigDecimal(heavyMatcher.group(1)));
            }

            // 提取垃圾类型
            Pattern typePattern = Pattern.compile("垃圾类型[:：]([^;]+)");
            Matcher typeMatcher = typePattern.matcher(trimmed);
            if (typeMatcher.find()) {
                result.setGarbageType(typeMatcher.group(1).trim());
            }

            // 提取判断依据
            Pattern basisPattern = Pattern.compile("判断依据[:：](.+)");
            Matcher basisMatcher = basisPattern.matcher(trimmed);
            if (basisMatcher.find()) {
                result.setJudgmentBasis(basisMatcher.group(1).trim());
            }

            // 验证必要字段
            if (result.getDetails() == null || result.getGarbageType() == null) {
                log.warn("解析结果不完整，响应内容：{}", response);
            }

            return result;

        } catch (Exception e) {
            log.error("解析垃圾分析响应失败，响应内容：{}", response, e);
            throw new RuntimeException("解析AI响应失败：" + e.getMessage(), e);
        }
    }
}
