// /server/game/instance/TurnTimer.js

class TurnTimer {
    /**
     * Конструктор таймера хода.
     * @param {number} turnDurationMs - Длительность хода в миллисекундах.
     * @param {number} updateIntervalMs - Интервал для отправки обновлений времени клиентам (в мс).
     * @param {function} onTimeoutCallback - Колбэк, вызываемый при истечении времени хода.
     * @param {function} onTickCallback - Колбэк, вызываемый на каждом тике обновления (передает remainingTime, isPlayerTurnForTimer).
     */
    constructor(turnDurationMs, updateIntervalMs, onTimeoutCallback, onTickCallback) {
        this.turnDurationMs = turnDurationMs;
        this.updateIntervalMs = updateIntervalMs;
        this.onTimeoutCallback = onTimeoutCallback;
        this.onTickCallback = onTickCallback;

        this.timerId = null; // ID для setTimeout (обработка таймаута)
        this.updateIntervalId = null; // ID для setInterval (обновление клиента)
        this.startTime = 0; // Время начала текущего отсчета (Date.now())
        this.isRunning = false;
        this.isCurrentPlayerActualTurnForTick = false; // Храним, для чьего хода запущен таймер (для onTickCallback)
        this.isAiCurrentlyMakingMove = false; // Флаг, что сейчас ход AI (таймер не тикает для игрока)

        // console.log(`[TurnTimer] Initialized with duration: ${turnDurationMs}ms, update interval: ${updateIntervalMs}ms`);
    }

    /**
     * Запускает или перезапускает таймер хода.
     * @param {boolean} isPlayerTurn - true, если сейчас ход слота 'player', false - если ход слота 'opponent'.
     * @param {boolean} isAiTurn - true, если текущий ход делает AI (в этом случае таймер для реального игрока не тикает).
     */
    start(isPlayerTurn, isAiTurn = false) {
        this.clear(); // Сначала очищаем предыдущие таймеры

        this.isCurrentPlayerActualTurnForTick = isPlayerTurn; // Сохраняем, чей ход для onTick
        this.isAiCurrentlyMakingMove = isAiTurn;

        // Таймер и отсчет времени запускаются только если это НЕ ход AI
        if (this.isAiCurrentlyMakingMove) {
            this.isRunning = false;
            // console.log(`[TurnTimer] Start called, but it's AI's turn. Timer not started for player.`);
            // Уведомляем один раз, что таймер неактивен (ход AI)
            if (this.onTickCallback) {
                this.onTickCallback(null, this.isCurrentPlayerActualTurnForTick);
            }
            return;
        }

        this.startTime = Date.now();
        this.isRunning = true;
        // console.log(`[TurnTimer] Started for ${isPlayerTurn ? 'Player' : 'Opponent'} at ${new Date(this.startTime).toLocaleTimeString()}. AI turn: ${isAiTurn}`);

        // Таймер на истечение общего времени хода
        this.timerId = setTimeout(() => {
            // console.log(`[TurnTimer] Timeout occurred! Was running: ${this.isRunning}`);
            if (this.isRunning) { // Дополнительная проверка, что таймер все еще должен был работать
                this.isRunning = false; // Помечаем, что таймер больше не работает
                if (this.onTimeoutCallback) {
                    this.onTimeoutCallback();
                }
                this.clear(); // Очищаем и интервал обновления после таймаута
            }
        }, this.turnDurationMs);

        // Интервал для отправки обновлений клиентам
        this.updateIntervalId = setInterval(() => {
            if (!this.isRunning) { // Если таймер был остановлен (например, ход сделан или игра окончена)
                this.clear(); // Убедимся, что интервал тоже очищен
                return;
            }

            const elapsedTime = Date.now() - this.startTime;
            const remainingTime = Math.max(0, this.turnDurationMs - elapsedTime);

            if (this.onTickCallback) {
                // Передаем isCurrentPlayerActualTurnForTick, чтобы клиент знал, для чьего хода это время
                this.onTickCallback(remainingTime, this.isCurrentPlayerActualTurnForTick);
            }

            if (remainingTime <= 0 && this.isRunning) { // Если время вышло по интервалу (на всякий случай, setTimeout должен сработать)
                // console.log(`[TurnTimer] Remaining time reached 0 in interval. Forcing timeout logic.`);
                // Не вызываем onTimeoutCallback здесь напрямую, чтобы избежать двойного вызова,
                // setTimeout должен это обработать. Просто очищаем интервал.
                this.clear(); // Очищаем интервал, setTimeout сработает для onTimeoutCallback
            }
        }, this.updateIntervalMs);

        // Отправляем начальное значение немедленно
        if (this.onTickCallback) {
            this.onTickCallback(this.turnDurationMs, this.isCurrentPlayerActualTurnForTick);
        }
    }

    /**
     * Очищает (останавливает) все активные таймеры (setTimeout и setInterval).
     */
    clear() {
        if (this.timerId) {
            clearTimeout(this.timerId);
            this.timerId = null;
        }
        if (this.updateIntervalId) {
            clearInterval(this.updateIntervalId);
            this.updateIntervalId = null;
        }
        this.isRunning = false;
        this.startTime = 0;
        // console.log(`[TurnTimer] Cleared.`);
    }

    /**
     * Проверяет, активен ли таймер в данный момент.
     * @returns {boolean}
     */
    isActive() {
        return this.isRunning;
    }
}

module.exports = TurnTimer;