// app.js (оркестратор)
import { fetchHealth, fetchHistory } from "./data.js";
import { state, addSignals, resetBufferTracking, updatePeakHolder, forceResetPeak, getPeakInfo } from "./state.js";
import { initDOM, setStatus, setMeta, setBars, setSignal, DOM } from "./ui.js";
import { initAccordion } from "./accordion.js";
import { drawChart } from "./chart.js";
import { initResize } from "./layout.js";
import { initCamera } from "./camera.js";

let lastChart: number = 0;
let connectionLost: boolean = false;
let consecutiveErrors: number = 0;
const MAX_ERRORS: number = 3;
let pollTimer: number | null = null;

// ================= INIT =================
window.addEventListener("DOMContentLoaded", () => {
  initDOM();
  initAccordion();
  initResize();
  initCamera();
});

document.addEventListener("keydown", (e: KeyboardEvent) => {
  const leftPanel = document.getElementById("leftPanel");
  const rightPanel = document.getElementById("rightPanel");

  switch(e.key.toLowerCase()) {
    case 'c':
      const camBtn = document.getElementById('camToggle');
      if (camBtn) camBtn.click();
      break;
    case 'f':
      if (leftPanel) {
        leftPanel.style.width = "100%";
        if (rightPanel) rightPanel.style.display = "none";
      }
      break;
    case 'escape':
      if (rightPanel) rightPanel.style.display = "flex";
      if (leftPanel && rightPanel) {
        const total = window.innerWidth;
        const leftWidth = total * 0.6;
        leftPanel.style.flex = `0 0 ${leftWidth}px`;
        rightPanel.style.flex = `0 0 ${total - leftWidth}px`;
      }
      break;
  }
});

// ================= UPDATE =================
async function update(): Promise<void> {
  try {
    const [health, history] = await Promise.all([
      fetchHealth(),
      fetchHistory()
    ]);

    consecutiveErrors = 0;

    if (connectionLost) {
      console.log("[app] Соединение восстановлено");
    }

    const isOnline = health.pipe_alive && health.has_data;

    if (isOnline) {
      setStatus("На связи");
      connectionLost = false;
    } else {
      setStatus("Нет связи", true);
      if (!connectionLost) resetBufferTracking();
      connectionLost = true;
    }

    const arr = Array.isArray(history.bytes) ? history.bytes : [];
    const raw = arr[arr.length - 1] ?? 0;

    if (arr.length > 0 && isOnline) {
      const bufferSize = health.stats?.filled ?? 0;
      addSignals(arr, bufferSize);
    }

    const value = raw & 0x3F;
    const level = (raw >> 6) & 0x3;
    const percent = (value / 63) * 100;

    if (isOnline) {
        const displayValue = updatePeakHolder(percent);
        setBars(displayValue);
        setSignal(level);
    } else {
    // Сервер НЕ на связи - сбрасываем индикаторы в 0 и делаем серыми
        setBars(0, true);    // true = режим "нет соединения"
        setSignal(0, true);  // true = режим "нет соединения"
    }

    if (DOM.lastByte) {
      DOM.lastByte.textContent = isOnline ? value.toString() : "--";
    }

    const uptime = Math.round(health.uptime_sec || 0);
    const filled = health.stats?.filled ?? 0;
    const Bps = Math.round(health.stats?.bytes_per_sec ?? 0);

    setMeta(`Работа: ${uptime}s | Буфер: ${filled} | Приём: ${Bps} B/s`);

    if (DOM.history) {
      DOM.history.innerHTML = arr
        .map((b, i) => `[${i}] ${(b & 0xFF).toString(2).padStart(8, "0")} = ${b & 0xFF}`)
        .join("<br>");
    }

    const now = performance.now();
    if (now - lastChart > 100 && DOM.canvas) {
      drawChart(DOM.canvas, state.signalHistory);
      lastChart = now;
    }

  } catch (e) {
    consecutiveErrors++;
    if (consecutiveErrors === 1) console.warn("[app] Сервер недоступен, ждём...");

    setStatus("СЕРВЕР НЕДОСТУПЕН", true);
    setBars(0, true);
    setSignal(0, true);
    resetBufferTracking();

    if (DOM.lastByte) DOM.lastByte.textContent = "--";

    if (consecutiveErrors >= MAX_ERRORS && pollTimer) {
      clearInterval(pollTimer);
      pollTimer = window.setInterval(update, 2000);
      console.log("[app] Замедлили опрос до 2с");
    }
  }
}

function startPolling(): void {
  if (pollTimer) clearInterval(pollTimer);
  if (consecutiveErrors > 0) update();
  pollTimer = window.setInterval(update, 500);
}

window.addEventListener("focus", () => {
  if (consecutiveErrors >= MAX_ERRORS) {
    console.log("[app] Окно в фокусе, ускоряем опрос");
    consecutiveErrors = 0;
    startPolling();
  }
});

startPolling();
update();