// state.ts - Peak Holder алгоритм с таймером

interface AppState {
  maxPoints: number;
  signalHistory: number[];
  lastBufferSize: number;

  // Peak Holder параметры
  peakValue: number;           // Текущее удерживаемое пиковое значение
  currentValue: number;        // Текущее реальное значение (без сглаживания)
  peakTimer: number | null;    // Таймер для сброса пика
  peakHoldTime: number;        // Время удержания пика в миллисекундах
}

export const state: AppState = {
  maxPoints: 1000,
  signalHistory: [],
  lastBufferSize: 0,

  peakValue: 0,
  currentValue: 0,
  peakTimer: null,
  peakHoldTime: 3000,  // миллисекунды удержания пика
};

/**
 * Основная функция peak holder
 * @param target - новое значение (0-63)
 * @returns значение для отображения (пик, если таймер активен)
 */
export function updatePeakHolder(target: number): number {
  // Обновляем текущее значение
  state.currentValue = target;

  // Если новое значение больше текущего пика
  if (target > state.peakValue) {
    // Устанавливаем новый пик
    state.peakValue = target;

    // Сбрасываем и перезапускаем таймер
    resetPeakTimer();
    startPeakTimer();
  }

  // Возвращаем текущий пик для отображения
  return state.peakValue;
}

/**
 * Запуск таймера сброса пика
 */
function startPeakTimer(): void {
  if (state.peakTimer !== null) {
    clearTimeout(state.peakTimer);
  }

  state.peakTimer = window.setTimeout(() => {
    resetPeak();
  }, state.peakHoldTime);
}

/**
 * Сброс таймера пика
 */
function resetPeakTimer(): void {
  if (state.peakTimer !== null) {
    clearTimeout(state.peakTimer);
    state.peakTimer = null;
  }
}

/**
 * Сброс пикового значения до текущего уровня
 */
function resetPeak(): void {
  state.peakValue = state.currentValue;
  state.peakTimer = null;

  // Опционально: лог для отладки
  // console.log(`[PeakHolder] Reset to: ${state.peakValue}`);
}

/**
 * Принудительный сброс пика (например, при потере связи)
 */
export function forceResetPeak(): void {
  resetPeakTimer();
  state.peakValue = 0;
  state.currentValue = 0;
}

/**
 * Обновление времени удержания пика
 * @param ms - время в миллисекундах
 */
export function setPeakHoldTime(ms: number): void {
  state.peakHoldTime = ms;
}

/**
 * Получение текущего состояния пика (для отладки)
 */
export function getPeakInfo(): { peak: number; current: number; timerActive: boolean } {
  return {
    peak: state.peakValue,
    current: state.currentValue,
    timerActive: state.peakTimer !== null,
  };
}

// ===== ОСТАВЛЯЕМ СУЩЕСТВУЮЩИЕ ФУНКЦИИ БЕЗ ИЗМЕНЕНИЙ =====

export function addSignal(value: number): void {
  state.signalHistory.push(value);
  if (state.signalHistory.length > state.maxPoints) {
    state.signalHistory = state.signalHistory.slice(-state.maxPoints);
  }
}

export function addSignals(values: number[], bufferSize: number): void {
  if (!Array.isArray(values) || values.length === 0) return;

  const newBytes = bufferSize - state.lastBufferSize;

  if (newBytes > 0 && newBytes <= values.length) {
    const fresh = values.slice(-newBytes);
    const decoded = fresh.map(b => b & 0x3F);
    state.signalHistory.push(...decoded);
  }

  state.lastBufferSize = bufferSize;

  if (state.signalHistory.length > state.maxPoints) {
    state.signalHistory = state.signalHistory.slice(-state.maxPoints);
  }
}

export function resetBufferTracking(): void {
  state.lastBufferSize = 0;
  forceResetPeak(); // Также сбрасываем пик при потере связи
}