// js/logs.ts - Логика для страницы журнала логов

import { drawChart } from './chart.js';

// ============================================
// ТИПЫ
// ============================================

interface LogFileInfo {
    name: string;
    path: string;
    size: number;
    mod_time: string;
    time: string;
    date: string;
    hour: number;
    is_active: boolean;
}

interface LogSample {
    ts: number;
    time: string;
    value: number;
    amplitude: number;
    signal: number;
    strength_name: string;
}

interface LogDataResponse {
    filename: string;
    total: number;
    page: number;
    page_size: number;
    total_pages: number;
    has_previous: boolean;
    has_next: boolean;
    start_index: number;
    end_index: number;
    samples: LogSample[];
    stats: {
        total_points: number;
        amplitude_over_0: number;
        signal_over_10: number;
    };
    order: string;
}

interface Event {
    time: string;
    event: string;
}

interface EventsResponse {
    events: Event[];
    total: number;
    page: number;
    page_size: number;
    total_pages: number;
    has_previous: boolean;
    has_next: boolean;
    returned: number;
    start_index: number;
    end_index: number;
    order?: string;
}

// ============================================
// СОСТОЯНИЕ
// ============================================

interface AppState {
    currentFile: string | null;
    currentData: LogDataResponse | null;
    currentEvents: Event[];
    currentPage: number;
    totalPages: number;
    isLoading: boolean;
    // Для данных
    dataPage: number;
    dataTotalPages: number;
    isLoadingData: boolean;
}

const state: AppState = {
    currentFile: null,
    currentData: null,
    currentEvents: [],
    currentPage: 1,
    totalPages: 1,
    isLoading: false,
    dataPage: 1,
    dataTotalPages: 1,
    isLoadingData: false,
};

const PAGE_SIZE = 100;
const DATA_PAGE_SIZE = 100;

// ============================================
// DOM ЭЛЕМЕНТЫ
// ============================================

const DOM = {
    fileList: document.getElementById('fileList') as HTMLElement | null,
    logStats: document.getElementById('logStats') as HTMLElement | null,
    dataTableContainer: document.getElementById('dataTableContainer') as HTMLElement | null,
    logChart: document.getElementById('logChart') as HTMLCanvasElement | null,
    eventsContent: document.getElementById('eventsContent') as HTMLElement | null,
    serverTime: document.getElementById('server-time') as HTMLElement | null,

    // Боковая панель
    logsSidebar: document.querySelector('.logs-sidebar') as HTMLElement | null,
    logsContainer: document.querySelector('.logs-container') as HTMLElement | null,

    // Элементы пагинации для данных
    dataPageInfo: document.getElementById('dataPageInfo') as HTMLElement | null,
    dataPrevPageBtn: document.getElementById('dataPrevPage') as HTMLButtonElement | null,
    dataNextPageBtn: document.getElementById('dataNextPage') as HTMLButtonElement | null,
    dataFirstPageBtn: document.getElementById('dataFirstPage') as HTMLButtonElement | null,
    dataLastPageBtn: document.getElementById('dataLastPage') as HTMLButtonElement | null,
    dataPageInput: document.getElementById('dataPageInput') as HTMLInputElement | null,
    dataGoToPageBtn: document.getElementById('dataGoToPage') as HTMLButtonElement | null,

    // Элементы пагинации для событий
    pageInfo: document.getElementById('pageInfo') as HTMLElement | null,
    prevPageBtn: document.getElementById('prevPage') as HTMLButtonElement | null,
    nextPageBtn: document.getElementById('nextPage') as HTMLButtonElement | null,
    firstPageBtn: document.getElementById('firstPage') as HTMLButtonElement | null,
    lastPageBtn: document.getElementById('lastPage') as HTMLButtonElement | null,
    pageInput: document.getElementById('pageInput') as HTMLInputElement | null,
    goToPageBtn: document.getElementById('goToPage') as HTMLButtonElement | null,
};

// ============================================
// УПРАВЛЕНИЕ БОКОВОЙ ПАНЕЛЬЮ
// ============================================

/**
 * Показать/скрыть боковую панель в зависимости от активной вкладки
 */
function toggleSidebar(show: boolean): void {
    if (!DOM.logsSidebar || !DOM.logsContainer) return;

    if (show) {
        // Показываем панель
        DOM.logsSidebar.style.display = 'block';
        DOM.logsSidebar.style.flex = '0 0 280px';
        DOM.logsContainer.style.gap = '20px';
    } else {
        // Скрываем панель
        DOM.logsSidebar.style.display = 'none';
        DOM.logsSidebar.style.flex = '0 0 0';
        DOM.logsContainer.style.gap = '0';
    }
}

// ============================================
// ФУНКЦИИ ЗАГРУЗКИ ДАННЫХ
// ============================================

/**
 * Загрузка списка файлов
 */
async function loadFileList(): Promise<void> {
    try {
        const response = await fetch('/api/log/files');
        const files: LogFileInfo[] = await response.json();

        if (!DOM.fileList) return;

        DOM.fileList.innerHTML = '';
        files.forEach((file: LogFileInfo) => {
            const div = document.createElement('div');
            div.className = 'log-file-item';
            if (state.currentFile === file.name) {
                div.classList.add('active');
            }
            div.innerHTML = `
                <div class="file-name">${file.name}</div>
                <div class="file-info">${file.time} | ${(file.size / 1024).toFixed(1)} KB</div>
            `;
            div.addEventListener('click', () => {
                state.dataPage = 1;
                void loadFileData(file.name, 1);
            });
            DOM.fileList?.appendChild(div);
        });

        // Автоматически загружаем первый файл
        if (files.length > 0 && !state.currentFile) {
            state.dataPage = 1;
            await loadFileData(files[0].name, 1);
        }
    } catch (error) {
        console.error('[Logs] Ошибка загрузки списка файлов:', error);
    }
}

/**
 * Загрузка данных из файла с пагинацией
 */
async function loadFileData(filename: string, page: number = 1): Promise<void> {
    if (state.isLoadingData) return;

    state.currentFile = filename;
    state.dataPage = page;

    // Обновляем активный элемент в списке
    const items = document.querySelectorAll('.log-file-item');
    Array.from(items).forEach((el) => {
        el.classList.remove('active');
    });

    const activeItems = document.querySelectorAll('.log-file-item');
    for (let i = 0; i < activeItems.length; i++) {
        const item = activeItems[i] as HTMLElement;
        if (item.textContent?.includes(filename)) {
            item.classList.add('active');
            break;
        }
    }

    try {
        state.isLoadingData = true;

        // Показываем индикатор загрузки
        if (DOM.dataTableContainer) {
            DOM.dataTableContainer.innerHTML = '<div class="loading-indicator">⏳ Загрузка данных...</div>';
        }

        const url = `/api/log/data?file=${encodeURIComponent(filename)}&page=${page}&page_size=${DATA_PAGE_SIZE}`;
        console.log(`[Logs] Загрузка данных: страница ${page} для ${filename}`);

        const response = await fetch(url);

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        const data: LogDataResponse = await response.json();
        state.currentData = data;
        state.dataTotalPages = data.total_pages;

        renderData(data);
        updateDataPagination(data);

        console.log(`[Logs] Загружено: ${data.samples.length} записей, Страница: ${page}/${data.total_pages}`);
    } catch (error) {
        console.error('[Logs] Ошибка загрузки данных:', error);
        if (DOM.dataTableContainer) {
            DOM.dataTableContainer.innerHTML = `
                <div class="empty-state">
                    <div class="empty-message">Нет данных для отображения</div>
                    <div class="empty-hint">Файл пуст или данные ещё не поступили</div>
                </div>
            `;
        }
        if (DOM.dataPageInfo) {
            DOM.dataPageInfo.textContent = 'Нет записей';
        }
        if (DOM.dataFirstPageBtn) DOM.dataFirstPageBtn.disabled = true;
        if (DOM.dataPrevPageBtn) DOM.dataPrevPageBtn.disabled = true;
        if (DOM.dataNextPageBtn) DOM.dataNextPageBtn.disabled = true;
        if (DOM.dataLastPageBtn) DOM.dataLastPageBtn.disabled = true;
    } finally {
        state.isLoadingData = false;
    }
}

/**
 * Загрузка событий с пагинацией
 */
async function loadEvents(page: number = 1): Promise<void> {
    if (state.isLoading) return;

    try {
        state.isLoading = true;
        state.currentPage = page;

        if (DOM.eventsContent) {
            DOM.eventsContent.innerHTML = '<div class="loading-indicator">Загрузка событий...</div>';
        }

        const url = `/api/log/events?page=${page}&page_size=${PAGE_SIZE}&order=newest_first`;
        console.log(`[Logs] Загрузка событий: страница ${page}`);

        const response = await fetch(url);

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        const data: EventsResponse = await response.json();

        state.totalPages = data.total_pages;
        state.currentEvents = data.events || [];

        renderEvents(data);
        updatePagination(data);

        console.log(`[Logs] Загружено: ${data.returned} событий, Страница: ${page}/${data.total_pages}`);
    } catch (error) {
        console.error('[Logs] Ошибка загрузки событий:', error);
        if (DOM.eventsContent) {
            DOM.eventsContent.innerHTML = `
                <div class="empty-state">
                    <div class="empty-message">Нет событий</div>
                    <div class="empty-hint">Журнал событий пуст</div>
                </div>
            `;
        }
    } finally {
        state.isLoading = false;
    }
}

// ============================================
// ФУНКЦИИ ОТРИСОВКИ
// ============================================

/**
 * Отрисовка данных файла
 */
function renderData(data: LogDataResponse): void {
    const samples = data.samples || [];

    // Статистика
    if (DOM.logStats) {
        const stats = data.stats || { total_points: 0, amplitude_over_0: 0, signal_over_10: 0 };
        DOM.logStats.innerHTML = `
            <div class="log-stat-card">
                <div class="value">${stats.total_points}</div>
                <div class="label">Всего точек</div>
            </div>
            <div class="log-stat-card">
                <div class="value">${stats.amplitude_over_0}</div>
                <div class="label">Амплитуда > 0</div>
            </div>
            <div class="log-stat-card">
                <div class="value">${stats.signal_over_10}</div>
                <div class="label">Сигнал > 10</div>
            </div>
        `;
    }

    // График
    if (DOM.logChart && data.total > 0) {
        const history = samples.map((s: LogSample) => s.signal);
        drawChart(DOM.logChart, history);
    }

    // Таблица
    if (samples.length > 0 && DOM.dataTableContainer) {
        let html = `<table class="data-table">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Время</th>
                    <th>Амплитуда</th>
                    <th>Сигнал</th>
                </tr>
            </thead>
            <tbody>`;

        samples.forEach((s: LogSample, index: number) => {
            let ampClass = '';
            if (s.amplitude === 0) ampClass = 'strength-0';
            else if (s.amplitude === 1) ampClass = 'strength-1';
            else if (s.amplitude === 2) ampClass = 'strength-2';
            else if (s.amplitude === 3) ampClass = 'strength-3';

            const num = index + 1;

            html += `<tr>
                <td style="opacity:0.3;font-size:var(--font-size-xs);">${num}</td>
                <td>${s.time}</td>
                <td class="${ampClass}">${s.amplitude}</td>
                <td>${s.signal}</td>
            </tr>`;
        });

        html += '</tbody></table>';
        DOM.dataTableContainer.innerHTML = html;
    } else if (DOM.dataTableContainer) {
        DOM.dataTableContainer.innerHTML = `
            <div class="empty-state">
                <div class="empty-message">Нет данных</div>
                <div class="empty-hint">Выберите файл с данными</div>
            </div>
        `;
    }
}

/**
 * Отрисовка событий
 */
function renderEvents(data: EventsResponse): void {
    if (!DOM.eventsContent) return;

    let html = '';
    if (data.events.length === 0) {
        html = `
            <div class="empty-state">
                <div class="empty-message">Нет событий</div>
                <div class="empty-hint">Журнал событий пуст</div>
            </div>
        `;
    } else {
        data.events.forEach((e: Event, index: number) => {
            const num = index + 1;
            html += `<div>
                <span class="event-num">#${num}</span>
                <span class="event-time">[${e.time}]</span>
                ${e.event}
            </div>`;
        });
    }
    DOM.eventsContent.innerHTML = html;
}

// ============================================
// ПАГИНАЦИЯ ДЛЯ ДАННЫХ
// ============================================

function updateDataPagination(data: LogDataResponse): void {
    const { page, total_pages, has_previous, has_next, start_index, end_index, total } = data;

    if (DOM.dataPageInfo) {
        if (total === 0) {
            DOM.dataPageInfo.textContent = 'Нет записей';
        } else {
            DOM.dataPageInfo.textContent = `Страница ${page} из ${total_pages} (записи ${start_index}-${end_index} из ${total}) новые сверху`;
        }
    }

    if (DOM.dataFirstPageBtn) DOM.dataFirstPageBtn.disabled = !has_previous;
    if (DOM.dataPrevPageBtn) DOM.dataPrevPageBtn.disabled = !has_previous;
    if (DOM.dataNextPageBtn) DOM.dataNextPageBtn.disabled = !has_next;
    if (DOM.dataLastPageBtn) DOM.dataLastPageBtn.disabled = !has_next;

    if (DOM.dataPageInput) {
        DOM.dataPageInput.value = page.toString();
        DOM.dataPageInput.max = total_pages.toString();
    }
}

function goToDataPage(page: number): void {
    if (page < 1) page = 1;
    if (page > state.dataTotalPages) page = state.dataTotalPages;
    if (page === state.dataPage) return;
    if (!state.currentFile) return;

    void loadFileData(state.currentFile, page);
}

function goToDataFirstPage(): void {
    goToDataPage(1);
}

function goToDataLastPage(): void {
    goToDataPage(state.dataTotalPages);
}

function goToDataPreviousPage(): void {
    goToDataPage(state.dataPage - 1);
}

function goToDataNextPage(): void {
    goToDataPage(state.dataPage + 1);
}

// ============================================
// ПАГИНАЦИЯ ДЛЯ СОБЫТИЙ
// ============================================

function updatePagination(data: EventsResponse): void {
    const { page, total_pages, has_previous, has_next, start_index, end_index, total } = data;

    if (DOM.pageInfo) {
        if (total === 0) {
            DOM.pageInfo.textContent = 'Нет записей';
        } else {
            DOM.pageInfo.textContent = `Страница ${page} из ${total_pages} (записи ${start_index}-${end_index} из ${total}) новые сверху`;
        }
    }

    if (DOM.firstPageBtn) DOM.firstPageBtn.disabled = !has_previous;
    if (DOM.prevPageBtn) DOM.prevPageBtn.disabled = !has_previous;
    if (DOM.nextPageBtn) DOM.nextPageBtn.disabled = !has_next;
    if (DOM.lastPageBtn) DOM.lastPageBtn.disabled = !has_next;

    if (DOM.pageInput) {
        DOM.pageInput.value = page.toString();
        DOM.pageInput.max = total_pages.toString();
    }
}

function goToPage(page: number): void {
    if (page < 1) page = 1;
    if (page > state.totalPages) page = state.totalPages;
    if (page === state.currentPage) return;
    void loadEvents(page);
}

function goToFirstPage(): void {
    goToPage(1);
}

function goToLastPage(): void {
    goToPage(state.totalPages);
}

function goToPreviousPage(): void {
    goToPage(state.currentPage - 1);
}

function goToNextPage(): void {
    goToPage(state.currentPage + 1);
}

// ============================================
// ОБНОВЛЕНИЕ ВРЕМЕНИ
// ============================================

async function updateTime(): Promise<void> {
    try {
        const response = await fetch('/api/health');
        const data = await response.json();
        if (DOM.serverTime) {
            DOM.serverTime.textContent = data.server_time || new Date().toLocaleTimeString();
        }
    } catch (error) {
        if (DOM.serverTime) {
            DOM.serverTime.textContent = new Date().toLocaleTimeString();
        }
    }
}

// ============================================
// ИНИЦИАЛИЗАЦИЯ
// ============================================

function initDataPaginationControls(): void {
    const dataTab = document.getElementById('tab-data');
    if (!dataTab) return;

    let paginationContainer = document.getElementById('dataPaginationContainer');
    if (!paginationContainer) {
        const tableContainer = document.getElementById('dataTableContainer');
        if (!tableContainer) return;

        paginationContainer = document.createElement('div');
        paginationContainer.id = 'dataPaginationContainer';
        paginationContainer.className = 'pagination-container';
        paginationContainer.innerHTML = `
            <div class="pagination-controls">
                <button id="dataFirstPage" class="pagination-btn" title="Первая страница (самые новые)">⏮</button>
                <button id="dataPrevPage" class="pagination-btn" title="Предыдущая страница (более новые)">◀</button>
                <button id="dataNextPage" class="pagination-btn" title="Следующая страница (более старые)">▶</button>
                <button id="dataLastPage" class="pagination-btn" title="Последняя страница (самые старые)">⏭</button>
                <span class="pagination-goto">
                    <input type="number" id="dataPageInput" min="1" value="1" class="pagination-input">
                    <button id="dataGoToPage" class="pagination-btn pagination-goto-btn">Перейти</button>
                </span>
                <span id="dataPageInfo" class="pagination-info">Страница 1 из 1</span>
            </div>
        `;

        dataTab.insertBefore(paginationContainer, tableContainer);
    }

    DOM.dataFirstPageBtn = document.getElementById('dataFirstPage') as HTMLButtonElement | null;
    DOM.dataPrevPageBtn = document.getElementById('dataPrevPage') as HTMLButtonElement | null;
    DOM.dataNextPageBtn = document.getElementById('dataNextPage') as HTMLButtonElement | null;
    DOM.dataLastPageBtn = document.getElementById('dataLastPage') as HTMLButtonElement | null;
    DOM.dataPageInfo = document.getElementById('dataPageInfo') as HTMLElement | null;
    DOM.dataPageInput = document.getElementById('dataPageInput') as HTMLInputElement | null;
    DOM.dataGoToPageBtn = document.getElementById('dataGoToPage') as HTMLButtonElement | null;

    if (DOM.dataFirstPageBtn) DOM.dataFirstPageBtn.addEventListener('click', goToDataFirstPage);
    if (DOM.dataPrevPageBtn) DOM.dataPrevPageBtn.addEventListener('click', goToDataPreviousPage);
    if (DOM.dataNextPageBtn) DOM.dataNextPageBtn.addEventListener('click', goToDataNextPage);
    if (DOM.dataLastPageBtn) DOM.dataLastPageBtn.addEventListener('click', goToDataLastPage);

    if (DOM.dataGoToPageBtn) {
        DOM.dataGoToPageBtn.addEventListener('click', () => {
            if (DOM.dataPageInput) {
                const page = parseInt(DOM.dataPageInput.value);
                if (!isNaN(page) && page >= 1) {
                    goToDataPage(page);
                }
            }
        });
    }

    if (DOM.dataPageInput) {
        DOM.dataPageInput.addEventListener('keypress', (e: KeyboardEvent) => {
            if (e.key === 'Enter' && DOM.dataGoToPageBtn) {
                DOM.dataGoToPageBtn.click();
            }
        });
    }
}

function initEventsPaginationControls(): void {
    const eventsTab = document.getElementById('tab-events');
    if (!eventsTab) return;

    let paginationContainer = document.getElementById('eventsPaginationContainer');
    if (!paginationContainer) {
        const eventsContent = document.getElementById('eventsContent');
        if (!eventsContent) return;

        paginationContainer = document.createElement('div');
        paginationContainer.id = 'eventsPaginationContainer';
        paginationContainer.className = 'pagination-container';
        paginationContainer.innerHTML = `
            <div class="pagination-controls">
                <button id="firstPage" class="pagination-btn" title="Первая страница (самые новые)">⏮</button>
                <button id="prevPage" class="pagination-btn" title="Предыдущая страница (более новые)">◀</button>
                <button id="nextPage" class="pagination-btn" title="Следующая страница (более старые)">▶</button>
                <button id="lastPage" class="pagination-btn" title="Последняя страница (самые старые)">⏭</button>
                <span class="pagination-goto">
                    <input type="number" id="pageInput" min="1" value="1" class="pagination-input">
                    <button id="goToPage" class="pagination-btn pagination-goto-btn">Перейти</button>
                </span>
                <span id="pageInfo" class="pagination-info">Страница 1 из 1</span>
            </div>
        `;

        eventsTab.insertBefore(paginationContainer, eventsContent);
    }

    DOM.firstPageBtn = document.getElementById('firstPage') as HTMLButtonElement | null;
    DOM.prevPageBtn = document.getElementById('prevPage') as HTMLButtonElement | null;
    DOM.nextPageBtn = document.getElementById('nextPage') as HTMLButtonElement | null;
    DOM.lastPageBtn = document.getElementById('lastPage') as HTMLButtonElement | null;
    DOM.pageInfo = document.getElementById('pageInfo') as HTMLElement | null;
    DOM.pageInput = document.getElementById('pageInput') as HTMLInputElement | null;
    DOM.goToPageBtn = document.getElementById('goToPage') as HTMLButtonElement | null;

    if (DOM.firstPageBtn) DOM.firstPageBtn.addEventListener('click', goToFirstPage);
    if (DOM.prevPageBtn) DOM.prevPageBtn.addEventListener('click', goToPreviousPage);
    if (DOM.nextPageBtn) DOM.nextPageBtn.addEventListener('click', goToNextPage);
    if (DOM.lastPageBtn) DOM.lastPageBtn.addEventListener('click', goToLastPage);

    if (DOM.goToPageBtn) {
        DOM.goToPageBtn.addEventListener('click', () => {
            if (DOM.pageInput) {
                const page = parseInt(DOM.pageInput.value);
                if (!isNaN(page) && page >= 1) {
                    goToPage(page);
                }
            }
        });
    }

    if (DOM.pageInput) {
        DOM.pageInput.addEventListener('keypress', (e: KeyboardEvent) => {
            if (e.key === 'Enter' && DOM.goToPageBtn) {
                DOM.goToPageBtn.click();
            }
        });
    }
}

function initTabs(): void {
    const tabs = document.querySelectorAll('.tab-btn[data-tab]');
    tabs.forEach((btn) => {
        btn.addEventListener('click', () => {
            tabs.forEach((b) => b.classList.remove('active'));
            btn.classList.add('active');

            const tabName = btn.getAttribute('data-tab');
            const contents = document.querySelectorAll('.tab-content');
            contents.forEach((el) => el.classList.remove('active'));

            const targetTab = document.getElementById(`tab-${tabName}`);
            if (targetTab) targetTab.classList.add('active');

            // ===== УПРАВЛЕНИЕ БОКОВОЙ ПАНЕЛЬЮ =====
            if (tabName === 'data') {
                // Показываем боковую панель для вкладки "Данные"
                toggleSidebar(true);
                // Если данные ещё не загружены, загружаем
                if (!state.currentData) {
                    const firstFile = document.querySelector('.log-file-item');
                    if (firstFile) {
                        const fileName = firstFile.querySelector('.file-name')?.textContent;
                        if (fileName) {
                            void loadFileData(fileName, 1);
                        }
                    }
                }
            } else if (tabName === 'events') {
                // Скрываем боковую панель для вкладки "События"
                toggleSidebar(false);
                // Загружаем события, если их нет
                if (state.currentEvents.length === 0) {
                    void loadEvents(1);
                }
            }
        });
    });
}

async function init(): Promise<void> {
    console.log('[Logs] Инициализация...');

    // По умолчанию показываем боковую панель
    toggleSidebar(true);

    initDataPaginationControls();
    initEventsPaginationControls();
    initTabs();

    await loadFileList();

    await updateTime();
    setInterval(() => {
        void updateTime();
    }, 1000);

    // Проверяем, какая вкладка активна при загрузке
    const dataTab = document.getElementById('tab-data');
    const eventsTab = document.getElementById('tab-events');

    if (eventsTab && eventsTab.classList.contains('active')) {
        toggleSidebar(false);
        await loadEvents(1);
    } else {
        toggleSidebar(true);
    }

    console.log('[Logs] Инициализация завершена');
}

// ============================================
// ЗАПУСК
// ============================================

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        void init();
    });
} else {
    void init();
}