package com.cmvr.test.flow.runtime.operator.edge;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.test.enums.ActionEnum;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import com.cmvr.test.model.vo.inspection.InspectionManualReviewConfigVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * 创建待人工复核巡检结果，工作流不等待人工处理。
 *
 * <p>输入参数见{@link InspectionManualReviewConfigVO}。节点只登记已由前置组件保存到MinIO的
 * 图片或视频地址，不复制媒体文件。节点执行后立即返回PENDING，人工通过巡检结果接口复核。</p>
 */
@Service
public class EdgeManualInspectionOperateService implements EdgeOperateService
{
    private static final String RESULT_MARKER = "_inspectionResult";

    @Override
    public boolean supports(ActionEnum action)
    {
        return ActionEnum.INSPECTION_MANUAL_REVIEW_CREATE.equals(action);
    }

    @Override
    public TaskNodeExecuteResult execute(TaskNodeExecuteMessage message)
    {
        JSONObject input = message.getInputParams() == null ? new JSONObject() : message.getInputParams();
        InspectionManualReviewConfigVO config = input.to(InspectionManualReviewConfigVO.class);
        String resultName = StringUtils.defaultIfBlank(config.getResultName(), "人工巡检");
        JSONArray mediaList = resolveMediaList(input);
        if (mediaList.isEmpty())
        {
            throw new GlobalException("人工巡检至少需要一张图片或一个视频");
        }

        JSONObject inspectionResult = new JSONObject();
        inspectionResult.put("resultType", "MANUAL");
        inspectionResult.put("resultStatus", "PENDING");
        inspectionResult.put("resultName", resultName);
        inspectionResult.put("evidenceUrl", mediaList.getJSONObject(0).getString("mediaUrl"));
        inspectionResult.put("evidenceType", mediaList.getJSONObject(0).getString("mediaType"));
        inspectionResult.put("mediaList", mediaList);
        inspectionResult.put("rawResult", new JSONObject()
                .fluentPut("reviewCriteria", config.getReviewCriteria())
                .fluentPut("defaultAlarmLevel", config.getDefaultAlarmLevel()));

        JSONObject output = new JSONObject();
        output.put("resultStatus", "PENDING");
        output.put("mediaList", mediaList);
        output.put(RESULT_MARKER, inspectionResult);
        return TaskNodeExecuteResult.success(output);
    }

    /**
     * 合并mediaList、imageUrl和videoUrl，并统一为标准媒体对象数组。
     */
    private JSONArray resolveMediaList(JSONObject input)
    {
        JSONArray result = new JSONArray();
        Object raw = input.get("mediaList");
        if (raw instanceof JSONArray)
        {
            for (Object item : (JSONArray) raw)
            {
                addMedia(result, item, null);
            }
        }
        else if (raw instanceof Collection)
        {
            for (Object item : (Collection<?>) raw)
            {
                addMedia(result, item, null);
            }
        }
        else
        {
            addMedia(result, raw, null);
        }
        addMedia(result, input.get("imageUrl"), "IMAGE");
        addMedia(result, input.get("videoUrl"), "VIDEO");
        return result;
    }

    /** 支持标准媒体对象，也兼容历史工作流直接传入URL字符串。 */
    private void addMedia(JSONArray target, Object value, String defaultType)
    {
        if (value == null)
        {
            return;
        }
        if (value instanceof JSONObject)
        {
            JSONObject source = (JSONObject) value;
            String url = StringUtils.trimToNull(source.getString("mediaUrl"));
            if (url != null)
            {
                target.add(new JSONObject()
                        .fluentPut("mediaUrl", url)
                        .fluentPut("mediaType", StringUtils.defaultIfBlank(
                                source.getString("mediaType"), detectType(url))));
            }
            return;
        }
        String url = StringUtils.trimToNull(String.valueOf(value));
        if (url != null)
        {
            target.add(new JSONObject()
                    .fluentPut("mediaUrl", url)
                    .fluentPut("mediaType", StringUtils.defaultIfBlank(defaultType, detectType(url))));
        }
    }

    /** 未显式指定类型时，根据常见视频后缀推断，其余按图片处理。 */
    private String detectType(String url)
    {
        String normalized = StringUtils.lowerCase(url);
        return normalized.matches(".*\\.(mp4|avi|mov|mkv|webm)(\\?.*)?$") ? "VIDEO" : "IMAGE";
    }
}
