(function () {
    const state = {
        satellites: [],
        selectedSatelliteId: null,
        analysis: null,
        loading: false
    };

    document.addEventListener('DOMContentLoaded', init);

    async function init() {
        bindEvents();
        await loadSatellites();
    }

    function bindEvents() {
        document.getElementById('tle-analysis-refresh')?.addEventListener('click', async () => {
            state.selectedSatelliteId = null;
            state.analysis = null;
            state.loading = false;
            renderResults();
            await loadSatellites();
        });
        document.getElementById('tle-analysis-satellite-filter')?.addEventListener('input', renderSatellites);
        document.getElementById('tle-analysis-count')?.addEventListener('change', async () => {
            if (state.selectedSatelliteId) {
                await loadAnalysis(state.selectedSatelliteId);
            }
        });
    }

    async function loadSatellites() {
        showAlert('Загрузка списка спутников...', 'info');
        try {
            const response = await fetch('/api/tle-analysis/satellites');
            if (!response.ok) {
                throw new Error(await errorText(response));
            }
            state.satellites = normalizeSatelliteResponse(await response.json());
            renderSatellites();
            renderResults();
            clearAlert();
        } catch (error) {
            showAlert(`Не удалось загрузить спутники: ${error.message}`, 'danger');
        }
    }

    async function loadAnalysis(satelliteId) {
        state.loading = true;
        state.analysis = null;
        renderResults();
        showAlert('Формирование анализа TLE...', 'info');
        try {
            const params = new URLSearchParams({ tleCount: String(selectedTleCount()) });
            const response = await fetch(`/api/tle-analysis/satellites/${encodeURIComponent(satelliteId)}/analysis?${params}`);
            if (!response.ok) {
                throw new Error(await errorText(response));
            }
            state.analysis = await response.json();
            renderResults();
            clearAlert();
        } catch (error) {
            state.analysis = null;
            showAlert(`Не удалось сформировать анализ TLE: ${error.message}`, 'danger');
        } finally {
            state.loading = false;
            renderResults();
        }
    }

    function renderSatellites() {
        const tbody = document.getElementById('tle-analysis-satellites-body');
        if (!tbody) return;

        const filter = normalize(document.getElementById('tle-analysis-satellite-filter')?.value || '');
        const satellites = state.satellites.filter((satellite) => {
            if (!filter) return true;
            return normalize([
                satellite.id,
                satellite.catalogId,
                satellite.noradId,
                satellite.code,
                satellite.name,
                satellite.typeCode,
                satellite.tleRecordsCount
            ].join(' ')).includes(filter);
        });

        if (satellites.length === 0) {
            tbody.innerHTML = `<tr><td colspan="3" class="catalog-empty">Спутники не найдены</td></tr>`;
            return;
        }

        tbody.innerHTML = satellites.map((satellite) => {
            const active = Number(satellite.id) === Number(state.selectedSatelliteId) ? 'active' : '';
            const title = escapeHtml(satellite.name || satellite.code || `КА ${satellite.id}`);
            const catalogId = satellite.catalogId == null ? satellite.id : satellite.catalogId;
            const tleCount = Number(satellite.tleRecordsCount || 0);
            return `
                <tr class="${active}" data-satellite-id="${escapeHtml(satellite.id)}">
                    <td>${escapeHtml(catalogId)}</td>
                    <td>
                        <div class="catalog-main-text">${title}</div>
                        <div class="catalog-helper">${escapeHtml(satellite.code || '')} ${satellite.typeCode ? ' / ' + escapeHtml(satellite.typeCode) : ''}</div>
                        <div class="catalog-helper">TLE-записей: ${escapeHtml(tleCount)}</div>
                    </td>
                    <td>${satellite.noradId == null ? '—' : escapeHtml(satellite.noradId)}</td>
                </tr>`;
        }).join('');

        tbody.querySelectorAll('tr[data-satellite-id]').forEach((row) => {
            row.addEventListener('click', async () => {
                const satelliteId = Number(row.dataset.satelliteId);
                state.selectedSatelliteId = satelliteId;
                state.analysis = null;
                renderSatellites();
                renderSelectedSatellite();
                await loadAnalysis(satelliteId);
            });
        });
    }

    function renderSelectedSatellite() {
        const label = document.getElementById('tle-analysis-selected-satellite');
        if (!label) return;
        const satellite = state.satellites.find((item) => Number(item.id) === Number(state.selectedSatelliteId));
        if (!satellite) {
            label.textContent = 'Выберите спутник слева.';
            return;
        }
        const name = satellite.name || satellite.code || `КА ${satellite.id}`;
        const catalogId = satellite.catalogId == null ? satellite.id : satellite.catalogId;
        label.textContent = `КА ${catalogId}: ${name}${satellite.noradId == null ? '' : `, NORAD ${satellite.noradId}`}`;
    }

    function renderResults() {
        renderSelectedSatellite();
        const empty = document.getElementById('tle-analysis-empty');
        const wrap = document.getElementById('tle-analysis-table-wrap');
        const tbody = document.getElementById('tle-analysis-results-body');
        const summary = document.getElementById('tle-analysis-summary');
        if (!empty || !wrap || !tbody || !summary) return;

        if (state.loading) {
            empty.textContent = 'Формирование анализа TLE...';
            empty.classList.remove('d-none');
            wrap.classList.add('d-none');
            summary.textContent = '';
            tbody.innerHTML = '';
            return;
        }

        const rows = state.analysis?.rows || [];
        summary.textContent = rows.length ? `Записей TLE: ${rows.length}` : '';

        if (!state.selectedSatelliteId) {
            empty.textContent = 'Выберите спутник для загрузки TLE.';
            empty.classList.remove('d-none');
            wrap.classList.add('d-none');
            tbody.innerHTML = '';
            return;
        }

        if (rows.length === 0) {
            empty.textContent = 'Для выбранного спутника TLE не найдены.';
            empty.classList.remove('d-none');
            wrap.classList.add('d-none');
            tbody.innerHTML = '';
            return;
        }

        empty.classList.add('d-none');
        wrap.classList.remove('d-none');
        tbody.innerHTML = rows.map(renderAnalysisRow).join('');
    }

    function renderAnalysisRow(row) {
        const r = row.radiusVector || {};
        const discrepancy = row.discrepancy;
        const diffText = discrepancy
            ? `<div class="tle-analysis-discrepancy">${formatNumber(discrepancy.norm, 3)}</div>
               <div class="catalog-helper tle-analysis-vector">Δx=${formatNumber(discrepancy.dx, 3)}, Δy=${formatNumber(discrepancy.dy, 3)}, Δz=${formatNumber(discrepancy.dz, 3)}</div>
               <div class="catalog-helper">к предыдущей эпохе ${escapeHtml(formatDateTime(discrepancy.previousEpoch))}</div>`
            : '<span class="catalog-helper">не рассчитывается</span>';

        return `
            <tr>
                <td>${escapeHtml(row.index)}</td>
                <td>
                    <div>${escapeHtml(formatDateTime(row.epoch))}</div>
                    ${row.tleHeader ? `<div class="catalog-helper">${escapeHtml(row.tleHeader)}</div>` : ''}
                </td>
                <td>${escapeHtml(row.revolution)}</td>
                <td>${escapeHtml(row.noradId)}</td>
                <td class="tle-analysis-vector">
                    x=${formatNumber(r.x, 3)}<br>
                    y=${formatNumber(r.y, 3)}<br>
                    z=${formatNumber(r.z, 3)}
                </td>
                <td>${formatNumber(row.radiusNorm, 3)}</td>
                <td>${discrepancy ? formatNumber(discrepancy.epochDifferenceHours, 3) : '—'}</td>
                <td>${diffText}</td>
            </tr>`;
    }

    function normalizeSatelliteResponse(payload) {
        if (Array.isArray(payload)) {
            return payload;
        }
        if (Array.isArray(payload?.items)) {
            return payload.items;
        }
        if (Array.isArray(payload?.content)) {
            return payload.content;
        }
        return [];
    }

    function selectedTleCount() {
        const input = document.getElementById('tle-analysis-count');
        const value = Number(input?.value || 5);
        if (!Number.isFinite(value) || value < 1) {
            if (input) input.value = '5';
            return 5;
        }
        const count = Math.floor(value);
        if (input && String(count) !== input.value) {
            input.value = String(count);
        }
        return count;
    }

    function normalize(value) {
        return String(value || '').trim().toLowerCase();
    }

    function formatDateTime(value) {
        return value ? PcpUtcTime.formatDateTime(value) : '—';
    }

    function formatNumber(value, fractionDigits) {
        const number = Number(value);
        if (!Number.isFinite(number)) return '—';
        return number.toLocaleString('ru-RU', {
            minimumFractionDigits: fractionDigits,
            maximumFractionDigits: fractionDigits
        });
    }

    async function errorText(response) {
        const text = await response.text();
        if (!text) return `${response.status} ${response.statusText}`;
        try {
            const json = JSON.parse(text);
            return json.message || json.error || text;
        } catch (_) {
            return text;
        }
    }

    function showAlert(message, type) {
        const alert = document.getElementById('tle-analysis-alert');
        if (!alert) return;
        alert.innerHTML = `<div class="alert alert-${type} py-2" role="alert">${escapeHtml(message)}</div>`;
    }

    function clearAlert() {
        const alert = document.getElementById('tle-analysis-alert');
        if (alert) alert.innerHTML = '';
    }

    function escapeHtml(value) {
        return String(value ?? '')
            .replaceAll('&', '&amp;')
            .replaceAll('<', '&lt;')
            .replaceAll('>', '&gt;')
            .replaceAll('"', '&quot;')
            .replaceAll("'", '&#039;');
    }
})();
