// ui.ts - Управление UI элементами

export interface DOMElements {
    serverTime: HTMLElement | null;
    status: HTMLElement | null;
    meta: HTMLElement | null;
    latest: HTMLElement | null;
    lastByte: HTMLElement | null;
    history: HTMLElement | null;
    canvas: HTMLCanvasElement | null;
    bars: NodeListOf<HTMLElement>;
    barFill: HTMLElement | null;
    bar2: HTMLElement | null;
    bar3: HTMLElement | null;
    soundLevel: HTMLElement | null;
    heightLevel: HTMLElement | null;
    historyHeader: HTMLElement | null;
    historyBody: HTMLElement | null;
    audioIndicator: HTMLElement | null;
}

export const DOM: DOMElements = {
    serverTime: null,
    status: null,
    meta: null,
    latest: null,
    lastByte: null,
    history: null,
    canvas: null,
    bars: document.querySelectorAll(".sig-bar"),
    barFill: null,
    bar2: null,
    bar3: null,
    soundLevel: null,
    heightLevel: null,
    historyHeader: null,
    historyBody: null,
    audioIndicator: null,
};

export function initDOM(): void {
    DOM.serverTime = document.getElementById("server-time");
    DOM.status = document.getElementById("status");
    DOM.meta = document.getElementById("meta");
    DOM.latest = document.getElementById("latest");
    DOM.lastByte = document.getElementById("last-byte");
    DOM.history = document.getElementById("history");
    DOM.canvas = document.getElementById("signalChart") as HTMLCanvasElement;
    DOM.barFill = document.getElementById("bar1");
    DOM.bar2 = document.getElementById("bar2");
    DOM.bar3 = document.getElementById("bar3");
    DOM.soundLevel = document.getElementById("sound-level");
    DOM.heightLevel = document.getElementById("height-level");
    DOM.historyHeader = document.getElementById("history-header");
    DOM.historyBody = document.getElementById("history-body");
    DOM.bars = document.querySelectorAll(".sig-bar");
    DOM.audioIndicator = document.getElementById("audio-indicator");
}

export function setServerTime(v: string): void {
    if (DOM.serverTime) DOM.serverTime.textContent = v;
}

export function setStatus(v: string, isError: boolean = false): void {
    if (!DOM.status) return;
    DOM.status.textContent = v;

    DOM.status.classList.remove("status-ok", "status-error", "status-lost");

    if (isError) {
        if (v === "Нет связи") {
            DOM.status.classList.add("status-lost");
        } else {
            DOM.status.classList.add("status-error");
        }
    } else {
        DOM.status.classList.add("status-ok");
    }
}

export function setMeta(v: string): void {
    if (DOM.meta) DOM.meta.textContent = v;
}

// ===== ОСНОВНОЙ ПРОГРЕСС-БАР =====
export function setBars(p: number, noConnection: boolean = false): void {
    const el = DOM.barFill;
    if (!el) return;

    if (noConnection) {
        el.style.width = "0%";
        el.classList.add("no-connection");
    } else {
        el.classList.remove("no-connection");
        const percent = Math.max(0, Math.min(100, p));
        el.style.width = `${percent}%`;
        el.style.background = '#e6852d';
        el.style.backgroundColor = '#e6852d';
        el.style.backgroundImage = 'none';
    }
}

// ===== ИНДИКАТОРЫ УРОВНЯ СИГНАЛА =====
export function setSignal(level: number, noConnection: boolean = false): void {
    const bars = DOM.bars;
    if (!bars || bars.length < 3) return;

    bars.forEach(bar => {
        bar.classList.remove("active-1", "active-2", "active-3", "dim", "no-connection");
        if (noConnection) {
            bar.classList.add("no-connection");
        } else {
            bar.classList.add("dim");
        }
    });

    if (noConnection) return;

    if (level >= 1) {
        bars[0].classList.add("active-1");
        bars[0].classList.remove("dim");
    }
    if (level >= 2) {
        bars[1].classList.add("active-2");
        bars[1].classList.remove("dim");
    }
    if (level >= 3) {
        bars[2].classList.add("active-3");
        bars[2].classList.remove("dim");
    }
}

export function setAudioIndicator(active: boolean, level: number = 0): void {
    const el = DOM.audioIndicator;
    if (!el) return;

    // Проверяем громкость
    const volume = localStorage.getItem('gport_volume');
    const currentVolume = volume ? parseInt(volume) : 0;

    if (active && level > 0 && currentVolume > 0) {
        el.textContent = '🔊';
        el.style.color = '#00ff88';
        el.style.opacity = '1';
        el.style.animation = 'pulse 1s ease-in-out infinite';
        el.classList.remove('muted');
        el.classList.add('active');
    } else {
        el.textContent = '🔇';
        el.style.color = '#666';
        el.style.opacity = '0.5';
        el.style.animation = 'none';
        el.classList.add('muted');
        el.classList.remove('active');
    }
}

export function setSoundLevel(level: number): void {
    if (DOM.bar2) {
        const percent = Math.max(0, Math.min(100, level));
        DOM.bar2.style.width = `${percent}%`;
    }
    if (DOM.soundLevel) {
        DOM.soundLevel.textContent = Math.round(level).toString();
    }
}

export function setHeightLevel(level: number): void {
    if (DOM.bar3) {
        const percent = Math.max(0, Math.min(100, level));
        DOM.bar3.style.width = `${percent}%`;
    }
    if (DOM.heightLevel) {
        DOM.heightLevel.textContent = Math.round(level).toString();
    }
}

// ===== 8 КАНАЛОВ =====
export interface ChannelState {
    value: number;          // Максимальное значение (для прогресс-бара)
    currentValue: number;   // Текущее значение (для отображения)
    strength: number;       // Максимальный уровень
    currentStrength: number; // Текущий уровень
    expanded: boolean;
}

export const channels: ChannelState[] = Array(8).fill(null).map(() => ({
    value: 0,
    currentValue: 0,
    strength: 0,
    currentStrength: 0,
    expanded: true
}));

export let channelElements: any[] = [];

export function initChannels() {
    const container = document.getElementById('channelsContainer');
    if (!container) return;

    container.innerHTML = '';
    channelElements = [];

    for (let i = 0; i < 8; i++) {
        const item = document.createElement('div');
        item.className = 'channel-item';
        item.dataset.channel = String(i);

        if (i === 0) {
            item.classList.add('channel-active');
        }

        item.innerHTML = `
            <div class="channel-header" data-channel="${i}">
                <span class="channel-label">Канал ${i + 1}</span>
                <span style="display:flex;align-items:center;gap:6px;">
                    <span class="channel-value" id="ch-val-${i}">--</span>
                    <span class="channel-toggle" id="ch-toggle-${i}">▼</span>
                </span>
            </div>
            <div class="channel-body" id="ch-body-${i}">
                <div class="channel-progress">
                    <div class="progress">
                        <div class="fill" id="ch-bar-${i}" style="width:0%; background: #e6852d;"></div>
                    </div>
                    <div class="signal-icon" id="ch-signal-${i}">
                        <div class="sig-bar sig-bar-1"></div>
                        <div class="sig-bar sig-bar-2"></div>
                        <div class="sig-bar sig-bar-3"></div>
                    </div>
                </div>
                <div class="channel-stats" id="ch-stats-${i}">--</div>
            </div>
        `;

        container.appendChild(item);

        channelElements[i] = {
            item: item,
            value: document.getElementById(`ch-val-${i}`),
            bar: document.getElementById(`ch-bar-${i}`),
            signal: document.getElementById(`ch-signal-${i}`),
            stats: document.getElementById(`ch-stats-${i}`),
            toggle: document.getElementById(`ch-toggle-${i}`),
            body: document.getElementById(`ch-body-${i}`)
        };

        const header = item.querySelector('.channel-header');
        header?.addEventListener('click', () => {
            toggleChannel(i);
        });
    }
}

export function toggleChannel(index: number) {
    const ch = channels[index];
    ch.expanded = !ch.expanded;

    const el = channelElements[index];
    if (!el) return;

    if (ch.expanded) {
        el.body.classList.remove('hidden');
        el.toggle.textContent = '▼';
    } else {
        el.body.classList.add('hidden');
        el.toggle.textContent = '▶';
    }
}

export function getChannelElement(index: number) {
    return channelElements[index] || null;
}

/**
 * Установка МАКСИМАЛЬНОГО значения для прогресс-бара
 * (используется для отображения пика)
 */
export function setChannelValue(index: number, value: number, strength: number) {
    if (index < 0 || index > 7) return;

    const ch = channels[index];
    const el = channelElements[index];
    if (!el) return;

    ch.value = value;
    ch.strength = strength;

    const maxValue = 63;
    const percent = (value / maxValue) * 100;

    // Обновляем прогресс-бар
    if (el.bar) {
        el.bar.style.width = `${Math.min(100, percent)}%`;
        el.bar.style.background = '#e6852d';
        el.bar.style.backgroundColor = '#e6852d';
        el.bar.style.backgroundImage = 'none';
    }

    // Обновляем индикатор сигнала (уровень)
    const bars = el.signal?.querySelectorAll('.sig-bar');
    if (bars) {
        bars.forEach((bar: Element, i: number) => {
            const isActive = i < strength;
            (bar as HTMLElement).style.opacity = isActive ? '1' : '0.2';
        });
    }

    // Обновляем статистику
    const strengthNames = ['Отсутствует', 'Низкая', 'Средняя', 'Высокая'];
    if (el.stats) {
        el.stats.textContent = `${ch.currentValue}/${maxValue} | ${strengthNames[ch.currentStrength] || '---'} (пик: ${value})`;
    }

    if (el.item) {
        el.item.classList.remove('no-data');
    }
}

/**
 * Установка ТЕКУЩЕГО значения для отображения в цифрах
 * (используется для показа реального состояния)
 */
export function setChannelCurrentValue(index: number, value: number, strength: number) {
    if (index < 0 || index > 7) return;

    const ch = channels[index];
    const el = channelElements[index];
    if (!el) return;

    ch.currentValue = value;
    ch.currentStrength = strength;

    // Обновляем числовое значение
    if (el.value) {
        el.value.textContent = value.toString();
    }

    // Обновляем статистику (показываем текущее значение и пик)
    const maxValue = 63;
    const strengthNames = ['Отсутствует', 'Низкая', 'Средняя', 'Высокая'];
    if (el.stats) {
        el.stats.textContent = `${value}/${maxValue} | ${strengthNames[strength] || '---'} (пик: ${ch.value})`;
    }

    // Обновляем индикатор сигнала (текущий уровень)
    const bars = el.signal?.querySelectorAll('.sig-bar');
    if (bars) {
        bars.forEach((bar: Element, i: number) => {
            const isActive = i < strength;
            // Если текущий уровень меньше максимального - добавляем класс dim
            if (isActive) {
                (bar as HTMLElement).classList.remove('dim');
                (bar as HTMLElement).classList.add('active-' + (i + 1));
            } else {
                (bar as HTMLElement).classList.add('dim');
                (bar as HTMLElement).classList.remove('active-' + (i + 1));
            }
        });
    }
}

export function updateAllChannels(rawData?: number[]) {
    for (let i = 0; i < 8; i++) {
        setChannelValue(i, 0, 0);
        setChannelCurrentValue(i, 0, 0);
        if (channelElements[i]) {
            channelElements[i].item.classList.remove('channel-active');
        }
    }

    if (rawData && rawData.length > 0) {
        const lastByte = rawData[rawData.length - 1];
        const value = lastByte & 0x3F;
        const strength = (lastByte >> 6) & 0x3;

        setChannelValue(0, value, strength);
        setChannelCurrentValue(0, value, strength);
        if (channelElements[0]) {
            channelElements[0].item.classList.add('channel-active');
        }

        if (DOM.lastByte) {
            DOM.lastByte.textContent = value.toString();
        }
    } else {
        if (DOM.lastByte) {
            DOM.lastByte.textContent = '--';
        }
    }
}

document.addEventListener('DOMContentLoaded', () => {
    initChannels();
    updateAllChannels();

    const expandAll = document.getElementById('expandAllBtn');
    const collapseAll = document.getElementById('collapseAllBtn');

    if (expandAll) {
        expandAll.addEventListener('click', () => {
            channels.forEach((ch, i) => {
                if (!ch.expanded) toggleChannel(i);
            });
        });
    }

    if (collapseAll) {
        collapseAll.addEventListener('click', () => {
            channels.forEach((ch, i) => {
                if (ch.expanded) toggleChannel(i);
            });
        });
    }
});