(function () {
    const pageRoot = document.getElementById('group-state-page');
    if (!pageRoot) {
        return;
    }

    const apiBase = '/api/catalog/group-states';
    const palette = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#17becf', '#bcbd22'];

    const state = {
        groups: [],
        selectedGroupId: null,
        details: null
    };

    function showAlert(message, type = 'danger') {
        const container = document.getElementById('group-state-alert');
        if (!message) {
            container.innerHTML = '';
            return;
        }
        container.innerHTML = `<div class="alert alert-${type} mb-3" role="alert">${message}</div>`;
    }

    async function requestJson(url, options = {}) {
        const response = await fetch(url, {
            headers: {
                'Content-Type': 'application/json'
            },
            ...options
        });

        if (response.status === 204) {
            return null;
        }

        const isJson = response.headers.get('content-type')?.includes('application/json');
        const payload = isJson ? await response.json() : await response.text();

        if (!response.ok) {
            if (payload && typeof payload === 'object') {
                if (payload.error) {
                    throw new Error(payload.error);
                }
                throw new Error(Object.values(payload).join('; '));
            }
            throw new Error(payload || `HTTP ${response.status}`);
        }

        return payload;
    }

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

    function formatInputDateTime(value) {
        return PcpUtcTime.toLocalInputValue(value, true);
    }

    function formatAngle(value) {
        return `${value.toFixed(2)}deg`;
    }

    function renderGroupList() {
        const tableBody = document.getElementById('group-state-list');
        tableBody.innerHTML = '';

        if (!state.groups.length) {
            tableBody.innerHTML = '<tr><td colspan="3" class="text-center text-muted py-4">Группировки не найдены</td></tr>';
            return;
        }

        state.groups.forEach(group => {
            const tr = document.createElement('tr');
            if (group.groupId === state.selectedGroupId) {
                tr.classList.add('table-active');
            }
            const interval = group.availableInterval
                ? `${formatDateTimeLabel(group.availableInterval.timeStart)} - ${formatDateTimeLabel(group.availableInterval.timeStop)}`
                : 'Нет пересечения';
            tr.innerHTML = `
                <td>
                    <div class="fw-semibold">${group.groupName}</div>
                    <div class="catalog-helper">#${group.groupId}</div>
                </td>
                <td>${group.satelliteCount}</td>
                <td class="group-state-interval-cell">${interval}</td>
            `;
            tr.addEventListener('click', () => selectGroup(group.groupId));
            tableBody.appendChild(tr);
        });
    }

    function renderTable(details) {
        const empty = document.getElementById('group-state-table-empty');
        const wrap = document.getElementById('group-state-table-wrap');

        if (!details || !details.availableInterval || !details.satellites.length) {
            empty.classList.remove('d-none');
            wrap.classList.add('d-none');
            wrap.innerHTML = '';
            return;
        }

        const headerCells = details.satellites
            .map(satellite => `<th>${escapeHtml(satellite.name)}<div class="catalog-helper">${escapeHtml(satellite.code || String(satellite.satelliteId))}</div></th>`)
            .join('');
        const rows = details.matrix.map(row => {
            const satellite = details.satellites.find(item => item.satelliteId === row.satelliteId);
            const cells = row.cells.map(cell => {
                const isDiagonal = cell.rowSatelliteId === cell.columnSatelliteId;
                if (isDiagonal) {
                    return '<td class="group-state-matrix-diagonal">-</td>';
                }
                return `
                    <td>
                        <div class="group-state-matrix-cell">
                            <div>dOMEGAB: ${formatAngle(cell.deltaOmegabDeg)}</div>
                            <div>du: ${formatAngle(cell.deltaUDeg)}</div>
                        </div>
                    </td>
                `;
            }).join('');

            return `
                <tr>
                    <th scope="row">
                        ${escapeHtml(satellite?.name || String(row.satelliteId))}
                        <div class="catalog-helper">${escapeHtml(satellite?.code || String(row.satelliteId))}</div>
                    </th>
                    ${cells}
                </tr>
            `;
        }).join('');

        wrap.innerHTML = `
            <table class="table table-bordered align-middle group-state-matrix-table mb-0">
                <thead>
                <tr>
                    <th>Спутник</th>
                    ${headerCells}
                </tr>
                </thead>
                <tbody>${rows}</tbody>
            </table>
        `;
        empty.classList.add('d-none');
        wrap.classList.remove('d-none');
    }

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

    function polarPoint(angleDeg, radius, center) {
        const angleRad = (angleDeg - 90) * Math.PI / 180;
        return {
            x: center + Math.cos(angleRad) * radius,
            y: center + Math.sin(angleRad) * radius
        };
    }

    function renderPolarChart(title, satellites, key, valueLabel) {
        const size = 320;
        const center = size / 2;
        const radius = 112;
        const innerRadius = 92;

        const ticks = satellites.map((satellite, index) => {
            const color = palette[index % palette.length];
            const start = polarPoint(satellite[key], innerRadius, center);
            const end = polarPoint(satellite[key], radius, center);
            return `<line x1="${start.x}" y1="${start.y}" x2="${end.x}" y2="${end.y}" stroke="${color}" stroke-width="6" stroke-linecap="round"></line>`;
        }).join('');

        const legend = satellites.map((satellite, index) => {
            const color = palette[index % palette.length];
            return `
                <div class="group-state-legend-item">
                    <span class="group-state-legend-color" style="background:${color}"></span>
                    <span>${escapeHtml(satellite.name)}: ${formatAngle(satellite[key])}</span>
                </div>
            `;
        }).join('');

        return `
            <div class="group-state-chart-card">
                <div class="group-state-chart-title">${title}</div>
                <svg viewBox="0 0 ${size} ${size}" class="group-state-chart-svg" aria-label="${escapeHtml(title)}">
                    <circle cx="${center}" cy="${center}" r="${radius}" class="group-state-chart-ring"></circle>
                    <circle cx="${center}" cy="${center}" r="${innerRadius}" class="group-state-chart-inner"></circle>
                    ${ticks}
                    <text x="${center}" y="${center - 4}" text-anchor="middle" class="group-state-chart-center">${escapeHtml(valueLabel)}</text>
                    <text x="${center}" y="${center + 18}" text-anchor="middle" class="group-state-chart-center-value">${satellites.length}</text>
                </svg>
                <div class="group-state-chart-legend">${legend}</div>
            </div>
        `;
    }

    function renderCharts(details) {
        const empty = document.getElementById('group-state-charts-empty');
        const container = document.getElementById('group-state-charts');

        if (!details || !details.availableInterval || !details.satellites.length) {
            empty.classList.remove('d-none');
            container.classList.add('d-none');
            container.innerHTML = '';
            return;
        }

        container.innerHTML = [
            renderPolarChart('ВУЗ орбиты', details.satellites, 'omegabDeg', 'OMEGAB'),
            renderPolarChart('Аргумент широты', details.satellites, 'uDeg', 'U')
        ].join('');
        empty.classList.add('d-none');
        container.classList.remove('d-none');
    }

    function renderSummary(details) {
        const summary = document.getElementById('group-state-summary');
        const timeInput = document.getElementById('group-state-time');
        const applyButton = document.getElementById('group-state-apply');

        if (!details) {
            summary.textContent = 'Выберите группировку слева.';
            timeInput.value = '';
            timeInput.min = '';
            timeInput.max = '';
            timeInput.disabled = true;
            applyButton.disabled = true;
            return;
        }

        if (!details.availableInterval) {
            summary.textContent = `${details.groupName}: нет общего доступного интервала расчета по всем спутникам ОГ.`;
            timeInput.value = '';
            timeInput.min = '';
            timeInput.max = '';
            timeInput.disabled = true;
            applyButton.disabled = true;
            return;
        }

        summary.innerHTML = `
            <div><strong>${escapeHtml(details.groupName)}</strong></div>
            <div>Доступный интервал: ${formatDateTimeLabel(details.availableInterval.timeStart)} - ${formatDateTimeLabel(details.availableInterval.timeStop)}</div>
        `;
        timeInput.disabled = false;
        applyButton.disabled = false;
        timeInput.min = formatInputDateTime(details.availableInterval.timeStart);
        timeInput.max = formatInputDateTime(details.availableInterval.timeStop);
        timeInput.value = formatInputDateTime(details.calculationTime || details.availableInterval.timeStart);
    }

    function renderDetails(details) {
        state.details = details;
        renderSummary(details);
        renderTable(details);
        renderCharts(details);
    }

    async function selectGroup(groupId, requestedTime = null) {
        state.selectedGroupId = groupId;
        renderGroupList();

        const query = requestedTime ? `?time=${encodeURIComponent(PcpUtcTime.toUtcIsoFromInput(requestedTime))}` : '';
        const details = await requestJson(`${apiBase}/${groupId}${query}`);
        renderDetails(details);
    }

    async function loadGroups() {
        state.groups = await requestJson(apiBase);
        renderGroupList();

        if (!state.groups.length) {
            renderDetails(null);
            return;
        }

        const selectedId = state.groups.some(group => group.groupId === state.selectedGroupId)
            ? state.selectedGroupId
            : state.groups[0].groupId;
        await selectGroup(selectedId);
    }

    document.getElementById('group-state-refresh').addEventListener('click', async () => {
        try {
            showAlert('');
            await loadGroups();
        } catch (error) {
            showAlert(error.message);
        }
    });

    document.getElementById('group-state-apply').addEventListener('click', async () => {
        if (!state.selectedGroupId) {
            showAlert('Сначала выберите группировку');
            return;
        }

        const time = document.getElementById('group-state-time').value;
        if (!time) {
            showAlert('Выберите момент времени');
            return;
        }

        try {
            showAlert('');
            await selectGroup(state.selectedGroupId, time);
        } catch (error) {
            showAlert(error.message);
        }
    });

    renderDetails(null);
    loadGroups().catch(error => showAlert(error.message));
})();
