/**
 * Flash Avoidance Module - 避光斑决策模块
 * 基于光斑检测结果，执行垂直结合避光斑策略
 *
 * 避光斑策略:
 * - 水平躲避: 根据光斑相对相机的左右位置，反向水平移动
 * - 垂直躲避: 根据光斑相对相机的上下位置，反向垂直移动
 *
 * 触发条件:
 * - 光斑被检测到且面积超过阈值
 */

const FlashAvoidanceModule = (() => {
    // 配置参数
    const config = {
        // 避光斑参数
        enabled: false,              // 是否启用避光斑
        avoidanceDistance: 3.0,       // 避光斑移动距离 (米)
        avoidanceHoldTime: 2000,      // 避光斑后悬停时间 (毫秒)
        minDetectionArea: 100,        // 最小检测面积阈值

        // 图像尺寸 (需要根据实际相机调整)
        imageWidth: 640,
        imageHeight: 480,

        // 阈值
        horizontalThreshold: 0.2,     // 水平方向检测阈值 (-1 ~ 1)
        verticalThreshold: 0.2,        // 垂直方向检测阈值 (-1 ~ 1)

        // 防抖
        debounceCount: 3,             // 需要连续检测N帧才触发避光斑
        debounceCooldown: 5000,        // 避光斑冷却时间 (毫秒)
    };

    // 状态
    let state = {
        isAvoiding: false,            // 是否正在执行避光斑
        debounceCounter: 0,           // 防抖计数器
        lastAvoidanceTime: 0,         // 上次避光斑时间
        detectionCount: 0,            // 连续检测计数
    };

    // 回调函数
    let onStatusUpdate = null;
    let onAvoidanceStart = null;
    let onAvoidanceEnd = null;

    // 外部依赖 (由主模块注入)
    let wsModule = null;

    /**
     * 初始化模块
     * @param {Object} options - 配置选项
     *   - wsModule: WsModule 实例 (用于获取无人机位置)
     *   - onStatusUpdate: 状态更新回调
     *   - onAvoidanceStart: 避光斑开始回调
     *   - onAvoidanceEnd: 避光斑结束回调
     */
    function init(options = {}) {
        wsModule = options.wsModule || null;
        onStatusUpdate = options.onStatusUpdate || null;
        onAvoidanceStart = options.onAvoidanceStart || null;
        onAvoidanceEnd = options.onAvoidanceEnd || null;

        if (options.config) {
            Object.assign(config, options.config);
        }

        console.log('[Flash Avoidance] 模块初始化完成');
        console.log('[Flash Avoidance] 避光斑距离:', config.avoidanceDistance, 'm');
        console.log('[Flash Avoidance] 最小检测面积:', config.minDetectionArea);
    }

    /**
     * 更新配置
     */
    function updateConfig(newConfig) {
        Object.assign(config, newConfig);
    }

    /**
     * 启用/禁用避光斑
     */
    function setEnabled(enabled) {
        config.enabled = enabled;
        if (statusCallback) {
            statusCallback({
                type: 'info',
                message: `避光斑模块 ${enabled ? '已启用' : '已禁用'}`
            });
        }
    }

    /**
     * 状态回调
     */
    let statusCallback = null;
    function setStatusCallback(callback) {
        statusCallback = callback;
    }

    /**
     * 处理光斑检测数据
     * @param {Object} detectionData - 检测数据 {cx, cy, area, sightX, sightY}
     * @returns {Object|null} - 避光斑指令或null
     */
    function processDetection(detectionData) {
        if (!config.enabled) {
            return null;
        }

        if (state.isAvoiding) {
            return null;  // 正在执行避光斑，忽略新检测
        }

        // 检查冷却时间
        const now = Date.now();
        if (now - state.lastAvoidanceTime < config.debounceCooldown) {
            return null;  // 冷却中
        }

        // 检查面积阈值
        if (detectionData.area < config.minDetectionArea) {
            state.detectionCount = 0;
            return null;
        }

        // 防抖计数
        state.detectionCount++;
        if (state.detectionCount < config.debounceCount) {
            return null;  // 还未达到连续检测阈值
        }

        // 计算相对位置
        const centerX = config.imageWidth / 2;
        const centerY = config.imageHeight / 2;

        const relativeX = (detectionData.cx - centerX) / centerX;
        const relativeY = (detectionData.cy - centerY) / centerY;

        // 判断是否需要避光斑
        let needAvoidance = false;
        let avoidX = 0, avoidY = 0, avoidZ = 0;

        // 水平避光斑 (X方向)
        if (Math.abs(relativeX) > config.horizontalThreshold) {
            // 光斑在右侧，无人机向左移动
            // 光斑在左侧，无人机向右移动
            avoidX = -relativeX * config.avoidanceDistance;
            needAvoidance = true;
        }

        // 垂直避光斑 (Z方向)
        if (Math.abs(relativeY) > config.verticalThreshold) {
            // 光斑在下方(cy > centerY)，无人机向上移动
            // 光斑在上方(cy < centerY)，无人机向下移动
            avoidZ = relativeY * config.avoidanceDistance;
            needAvoidance = true;
        }

        if (needAvoidance) {
            state.isAvoiding = true;
            state.lastAvoidanceTime = now;
            state.detectionCount = 0;

            const avoidanceCmd = {
                type: 'flash_avoidance',
                avoidX: avoidX,
                avoidY: avoidY,
                avoidZ: avoidZ,
                detectionData: {
                    cx: detectionData.cx,
                    cy: detectionData.cy,
                    area: detectionData.area,
                    relativeX: relativeX,
                    relativeY: relativeY
                }
            };

            if (onAvoidanceStart) {
                onAvoidanceStart(avoidanceCmd);
            }

            if (statusCallback) {
                statusCallback({
                    type: 'warning',
                    message: `检测到光斑，执行避光斑! 偏移: X=${avoidX.toFixed(1)}m, Z=${avoidZ.toFixed(1)}m`
                });
            }

            return avoidanceCmd;
        }

        return null;
    }

    /**
     * 结束避光斑
     */
    function endAvoidance() {
        if (state.isAvoiding) {
            state.isAvoiding = false;

            if (onAvoidanceEnd) {
                onAvoidanceEnd();
            }

            if (statusCallback) {
                statusCallback({
                    type: 'info',
                    message: '避光斑完成，返回正常控制'
                });
            }
        }
    }

    /**
     * 检查是否正在执行避光斑
     */
    function isAvoiding() {
        return state.isAvoiding;
    }

    /**
     * 计算避光斑目标位置
     * @param {Object} currentPos - 当前无人机位置 {x, y, z}
     * @param {Object} avoidanceCmd - 避光斑指令
     * @returns {Object} - 目标位置 {x, y, z}
     */
    function calculateAvoidanceTarget(currentPos, avoidanceCmd) {
        return {
            x: currentPos.x + avoidanceCmd.avoidX,
            y: currentPos.y + avoidanceCmd.avoidY,
            z: currentPos.z + avoidanceCmd.avoidZ
        };
    }

    /**
     * 获取当前状态
     */
    function getState() {
        return { ...state };
    }

    /**
     * 重置状态
     */
    function reset() {
        state = {
            isAvoiding: false,
            debounceCounter: 0,
            lastAvoidanceTime: 0,
            detectionCount: 0
        };
    }

    return {
        init,
        updateConfig,
        setEnabled,
        setStatusCallback,
        processDetection,
        endAvoidance,
        isAvoiding,
        calculateAvoidanceTarget,
        getState,
        reset
    };
})();
