// /server/game/logic/effectsLogic.js

// GAME_CONFIG и dataUtils будут передаваться в функции как параметры.
// const GAME_CONFIG_STATIC = require('../../core/config'); // Если нужен для внутренних констант
// const DATA_UTILS_STATIC = require('../../data/dataUtils'); // Если нужен для внутренних констант

/**
 * Обрабатывает активные эффекты (баффы/дебаффы) для бойца в конце его хода.
 * Длительность эффекта уменьшается на 1.
 * Периодические эффекты (DoT, сжигание ресурса и т.п.) срабатывают, если эффект не "justCast" в этом ходу.
 * @param {Array<object>} activeEffectsArray - Массив активных эффектов бойца (из gameState.player.activeEffects или gameState.opponent.activeEffects).
 * @param {object} ownerState - Состояние бойца, на котором эффекты (currentHp, currentResource и т.д.).
 * @param {object} ownerBaseStats - Базовые статы бойца (включая characterKey, name, maxHp, maxResource).
 * @param {string} ownerRoleInGame - Роль бойца в игре ('player' или 'opponent'), для контекста.
 * @param {object} currentGameState - Полное текущее состояние игры.
 * @param {function} addToLogCallback - Функция для добавления сообщений в лог игры.
 * @param {object} configToUse - Конфигурационный объект игры (GAME_CONFIG).
 * @param {object} dataUtils - Утилиты для доступа к данным игры (getCharacterData, getCharacterAbilities и т.д.).
 */
function processEffects(
    activeEffectsArray,
    ownerState,
    ownerBaseStats,
    ownerRoleInGame, // 'player' или 'opponent'
    currentGameState,
    addToLogCallback,
    configToUse,
    dataUtils
) {
    if (!activeEffectsArray || activeEffectsArray.length === 0) {
        return;
    }

    const ownerName = ownerBaseStats.name;
    const effectsToRemoveIndexes = [];

    for (let i = 0; i < activeEffectsArray.length; i++) {
        const effect = activeEffectsArray[i];

        // --- Применяем периодический эффект (DoT, сжигание ресурса и т.п.), если он не только что наложен ---
        if (!effect.justCast) {
            // 1. Урон от эффектов полного безмолвия (Гипнотический Взгляд, Раскол Разума)
            // Эти эффекты наносят урон цели В КОНЦЕ ее хода.
            if (effect.isFullSilence && typeof effect.power === 'number' && effect.power > 0) {
                const damage = effect.power; // Урон, заложенный в эффекте
                ownerState.currentHp = Math.max(0, Math.round(ownerState.currentHp - damage));
                if (addToLogCallback) {
                    addToLogCallback(
                        `😵 Эффект "${effect.name}" наносит ${damage} урона персонажу ${ownerName}! (HP: ${ownerState.currentHp}/${ownerBaseStats.maxHp})`,
                        configToUse.LOG_TYPE_DAMAGE
                    );
                }
            }

            // 2. Сжигание ресурса (Печать Слабости, Проклятие Увядания)
            // Эти эффекты сжигают ресурс цели В КОНЦЕ ее хода.
            // ID эффекта на цели имеет префикс 'effect_' + ID способности, которая его наложила.
            const isResourceBurnDebuff = effect.id === 'effect_' + configToUse.ABILITY_ID_SEAL_OF_WEAKNESS ||
                effect.id === 'effect_' + configToUse.ABILITY_ID_ALMAGEST_DEBUFF;
            if (isResourceBurnDebuff && typeof effect.power === 'number' && effect.power > 0) {
                const resourceToBurn = effect.power; // Количество ресурса, сжигаемое за ход
                if (ownerState.currentResource > 0) {
                    const actualBurn = Math.min(ownerState.currentResource, resourceToBurn);
                    ownerState.currentResource = Math.max(0, Math.round(ownerState.currentResource - actualBurn));
                    if (addToLogCallback) {
                        addToLogCallback(
                            `🔥 Эффект "${effect.name}" сжигает ${actualBurn} ${ownerBaseStats.resourceName} у ${ownerName}! (Ресурс: ${ownerState.currentResource}/${ownerBaseStats.maxResource})`,
                            configToUse.LOG_TYPE_EFFECT
                        );
                    }
                }
            }
            // Примечание: Отложенные эффекты (isDelayed: true, например, Сила Природы)
            // применяют свою основную силу в GameInstance.processPlayerAction (после атаки), а не здесь.
            // Здесь они просто тикают по длительности.
        }

        // --- Уменьшаем длительность ---
        effect.turnsLeft--;
        effect.justCast = false; // Эффект больше не считается "just cast" после обработки этого хода

        // --- Отмечаем для удаления, если длительность закончилась ---
        if (effect.turnsLeft <= 0) {
            effectsToRemoveIndexes.push(i);
            if (addToLogCallback) {
                addToLogCallback(
                    `Эффект "${effect.name}" на персонаже ${ownerName} закончился.`,
                    configToUse.LOG_TYPE_EFFECT
                );
            }
            // Если это был эффект, дающий блок, нужно обновить статус блокировки
            if (effect.grantsBlock) {
                updateBlockingStatus(ownerState); // Вызываем сразу, т.к. эффект удаляется
            }
            // Если это был эффект заглушения конкретной способности (playerSilencedOn_X),
            // то соответствующая запись в ownerState.disabledAbilities должна быть удалена в cooldownLogic.processDisabledAbilities.
            // Здесь мы просто удаляем сам эффект из activeEffects.
        }
    }

    // Удаляем эффекты с конца массива, чтобы не нарушить индексы при удалении
    for (let i = effectsToRemoveIndexes.length - 1; i >= 0; i--) {
        activeEffectsArray.splice(effectsToRemoveIndexes[i], 1);
    }

    // После удаления всех истекших эффектов, еще раз обновляем статус блока,
    // так как какой-то из удаленных эффектов мог быть последним дающим блок.
    // (хотя updateBlockingStatus вызывается и при удалении конкретного блокирующего эффекта)
    updateBlockingStatus(ownerState);
}

/**
 * Обновляет статус 'isBlocking' для бойца на основе его активных эффектов.
 * Боец считается блокирующим, если у него есть хотя бы один активный эффект с флагом grantsBlock: true.
 * @param {object} fighterState - Состояние бойца (объект из gameState.player или gameState.opponent).
 */
function updateBlockingStatus(fighterState) {
    if (!fighterState || !fighterState.activeEffects) {
        // console.warn("[EffectsLogic] updateBlockingStatus: fighterState or activeEffects missing.");
        if (fighterState) fighterState.isBlocking = false; // Если нет эффектов, то точно не блокирует
        return;
    }
    // Боец блокирует, если есть ХОТЯ БЫ ОДИН активный эффект, дающий блок
    const wasBlocking = fighterState.isBlocking;
    fighterState.isBlocking = fighterState.activeEffects.some(eff => eff.grantsBlock && eff.turnsLeft > 0);

    // Можно добавить лог, если статус блока изменился, для отладки
    // if (wasBlocking !== fighterState.isBlocking && addToLogCallback) {
    //     addToLogCallback(`${fighterState.name} ${fighterState.isBlocking ? 'встает в защиту' : 'перестает защищаться'} из-за эффектов.`, 'info');
    // }
}

/**
 * Проверяет, находится ли персонаж под действием полного безмолвия.
 * @param {object} characterState - Состояние персонажа из gameState.
 * @param {object} configToUse - Конфигурационный объект игры.
 * @returns {boolean} true, если персонаж под полным безмолвием, иначе false.
 */
function isCharacterFullySilenced(characterState, configToUse) {
    if (!characterState || !characterState.activeEffects) {
        return false;
    }
    return characterState.activeEffects.some(
        eff => eff.isFullSilence && eff.turnsLeft > 0
    );
}


module.exports = {
    processEffects,
    updateBlockingStatus,
    isCharacterFullySilenced
};