package com.ruoyi.ems.strategy.executor;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.ems.domain.OpEnergyStrategyStep;
import com.ruoyi.ems.domain.StrategyExecutionContext;
import com.ruoyi.ems.model.AbilityPayload;
import com.ruoyi.ems.service.IAbilityCallService;
import com.ruoyi.ems.service.IEmsObjAttrValueService;
import com.ruoyi.ems.service.IStepExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 能力调用执行器（完全通用化版本）
 *
 * 支持三种参数类型:
 * 1. null - 无参数能力
 * 2. Slider/Input - 单值参数
 * 3. Options - 枚举值参数
 */
@Slf4j
@Component
public class AbilityCallStepExecutor implements IStepExecutor {

    @Autowired
    private IAbilityCallService abilityCallService;

    @Autowired(required = false)
    private IEmsObjAttrValueService attrValueService;

    @Override
    public Object execute(OpEnergyStrategyStep step, StrategyExecutionContext context) throws Exception {
        // 构建能力调用载荷
        AbilityPayload payload = new AbilityPayload();
        payload.setObjCode(step.getTargetObjCode());
        payload.setObjType(step.getTargetObjType());
        payload.setModelCode(step.getTargetModelCode());
        payload.setAbilityKey(step.getAbilityKey());

        // 解析能力参数（完全通用化）
        String abilityParam = resolveAbilityParam(step, context);
        payload.setAbilityParam(abilityParam);

        log.info("策略步骤[{}]执行能力调用: objCode={}, abilityKey={}, param={}",
            step.getStepCode(), payload.getObjCode(), payload.getAbilityKey(), abilityParam);

        // 调用设备能力服务
        String result = abilityCallService.devAbilityCall(payload);

        log.info("策略步骤[{}]能力调用完成, 结果: {}", step.getStepCode(), result);

        return result;
    }

    /**
     * 解析能力参数（支持静态、上下文、属性值三种来源）
     */
    private String resolveAbilityParam(OpEnergyStrategyStep step, StrategyExecutionContext context) {
        String paramSource = step.getParamSource();
        if (paramSource == null) {
            paramSource = "STATIC";
        }

        switch (paramSource) {
            case "STATIC":
                // 静态参数：直接使用配置的参数值
                return step.getAbilityParam();

            case "CONTEXT":
                // 上下文参数：从执行上下文中获取动态值
                return resolveFromContext(step, context);

            case "ATTR":
                // 属性参数：从设备属性中获取实时值
                return resolveFromAttr(step, context);

            default:
                log.warn("未知的参数来源类型: {}, 使用静态参数", paramSource);
                return step.getAbilityParam();
        }
    }

    /**
     * 从上下文解析参数
     *
     * 支持格式:
     * 1. 单值: "1" 或 "50"（直接返回）
     * 2. 映射: {"value": "context.switchState"} → 从上下文获取
     */
    private String resolveFromContext(OpEnergyStrategyStep step, StrategyExecutionContext context) {
        String paramMapping = step.getParamMapping();

        // 如果没有映射配置，直接使用 abilityParam
        if (paramMapping == null || paramMapping.trim().isEmpty()) {
            return step.getAbilityParam();
        }

        try {
            JSONObject mapping = JSON.parseObject(paramMapping);

            // 如果是单值映射 {"value": "context.xxx"}
            if (mapping.containsKey("value")) {
                String contextPath = mapping.getString("value");
                Object value = getValueFromContext(contextPath, context);
                return value != null ? value.toString() : step.getAbilityParam();
            }

            // 其他映射情况（暂不支持多值）
            log.warn("不支持的上下文参数映射格式: {}", paramMapping);
            return step.getAbilityParam();

        } catch (Exception e) {
            log.error("解析上下文参数失败: {}", e.getMessage(), e);
            return step.getAbilityParam();
        }
    }

    /**
     * 从设备属性解析参数
     *
     * 支持格式:
     * 1. 单值: {"value": "D-B-QS-10000001.Switch"} → 从设备属性获取
     */
    private String resolveFromAttr(OpEnergyStrategyStep step, StrategyExecutionContext context) {
        if (attrValueService == null) {
            log.warn("属性值服务未注入，无法获取设备属性，使用静态参数");
            return step.getAbilityParam();
        }

        String paramMapping = step.getParamMapping();
        if (paramMapping == null || paramMapping.trim().isEmpty()) {
            return step.getAbilityParam();
        }

        try {
            JSONObject mapping = JSON.parseObject(paramMapping);

            // 如果是单值映射 {"value": "deviceCode.attrKey"}
            if (mapping.containsKey("value")) {
                String attrPath = mapping.getString("value");
                String[] parts = attrPath.split("\\.");

                if (parts.length == 2) {
                    String deviceCode = parts[0];
                    String attrKey = parts[1];
                    Object attrValue = queryDeviceAttr(step.getTargetModelCode(), deviceCode, attrKey);
                    return attrValue != null ? attrValue.toString() : step.getAbilityParam();
                }
            }

            log.warn("不支持的属性参数映射格式: {}", paramMapping);
            return step.getAbilityParam();

        } catch (Exception e) {
            log.error("解析属性参数失败: {}", e.getMessage(), e);
            return step.getAbilityParam();
        }
    }

    /**
     * 从上下文中获取值（支持嵌套路径）
     *
     * 示例:
     * - "switchState" → context.getVariable("switchState")
     * - "context.switchState" → context.getVariable("switchState")
     * - "stepResult.STEP_001.value" → context.getStepResult("STEP_001").value
     */
    private Object getValueFromContext(String path, StrategyExecutionContext context) {
        if (path == null || path.trim().isEmpty()) {
            return null;
        }

        // 移除 "context." 前缀
        if (path.startsWith("context.")) {
            path = path.substring(8);
        }

        String[] parts = path.split("\\.");
        Object current = null;

        if ("stepResult".equals(parts[0])) {
            // 从步骤结果中获取
            if (parts.length >= 2) {
                current = context.getStepResult(parts[1]);
                // 继续处理后续路径
                for (int i = 2; i < parts.length && current != null; i++) {
                    if (current instanceof JSONObject) {
                        current = ((JSONObject) current).get(parts[i]);
                    }
                }
            }
        } else {
            // 从变量中获取
            current = context.getVariable(parts[0]);
            // 继续处理后续路径
            for (int i = 1; i < parts.length && current != null; i++) {
                if (current instanceof JSONObject) {
                    current = ((JSONObject) current).get(parts[i]);
                }
            }
        }

        return current;
    }

    /**
     * 查询设备属性值
     */
    private Object queryDeviceAttr(String modelCode, String deviceCode, String attrKey) {
        try {
            if (attrValueService != null) {
                return attrValueService.selectObjAttrValue(modelCode, deviceCode, attrKey);
            }
        } catch (Exception e) {
            log.error("查询设备属性失败: deviceCode={}, attrKey={}", deviceCode, attrKey, e);
        }
        return null;
    }

    @Override
    public String getSupportedType() {
        return "ABILITY";
    }
}