/**
 * Settings Manager Module
 * Coordinates preset, calibration, and reference management
 */

import { PresetManager } from './settings/preset-manager.js';
import { CalibrationManager } from './settings/calibration-manager.js';
import { ReferenceManager } from './settings/reference-manager.js';
import { LaserManager } from './settings/laser-manager.js';
import { Debouncer, ButtonState, downloadJSON } from './utils.js';
import { renderIcons } from './icons.js';
import {
    createPlotlyPlot,
    togglePlotlyFullscreen,
    downloadPlotlyImage,
    cleanupPlotly
} from './plotly-utils.js';
import { apiGet, buildUrl } from './api-client.js';
import { API, TIMING, NOTIFICATION_TYPES } from './constants.js';

const { SUCCESS, ERROR, WARNING } = NOTIFICATION_TYPES;

export class SettingsManager {
    constructor(notifications, websocket, acquisition) {
        this.notifications = notifications;
        this.websocket = websocket;
        this.acquisition = acquisition;

        this.isInitialized = false;
        this.elements = {};
        this.headerElements = {};
        this.debouncer = new Debouncer();

        // Sub-managers
        this.presetManager = new PresetManager(notifications);
        this.calibrationManager = new CalibrationManager(notifications);
        this.referenceManager = new ReferenceManager(notifications);
        this.laserManager = new LaserManager(notifications);

        // Plots modal state
        this.currentPlotsData = null;

        // Bind handlers
        this.handleViewPlots = this.handleViewPlots.bind(this);
        this.handleViewCurrentPlots = this.handleViewCurrentPlots.bind(this);
    }

    async init() {
        try {
            this.cacheDom();
            this.initSubManagers();
            this.setupEventHandlers();
            await this.loadInitialData();

            this.isInitialized = true;
            console.log('Settings Manager initialized');
        } catch (err) {
            console.error('Settings Manager init failed:', err);
            this.notify(ERROR, 'Ошибка настроек', 'Не удалось инициализировать модуль настроек');
        }
    }

    cacheDom() {
        this.elements = {
            // Presets
            presetDropdown: document.getElementById('presetDropdown'),
            setPresetBtn: document.getElementById('setPresetBtn'),
            currentPreset: document.getElementById('currentPreset'),

            // Calibration
            currentCalibration: document.getElementById('currentCalibration'),
            startCalibrationBtn: document.getElementById('startCalibrationBtn'),
            calibrationSteps: document.getElementById('calibrationSteps'),
            calibrationStandards: document.getElementById('calibrationStandards'),
            progressText: document.getElementById('progressText'),
            calibrationNameInput: document.getElementById('calibrationNameInput'),
            saveCalibrationBtn: document.getElementById('saveCalibrationBtn'),
            calibrationDropdown: document.getElementById('calibrationDropdown'),
            setCalibrationBtn: document.getElementById('setCalibrationBtn'),
            viewPlotsBtn: document.getElementById('viewPlotsBtn'),
            deleteCalibrationBtn: document.getElementById('deleteCalibrationBtn'),
            clearCalibrationBtn: document.getElementById('clearCalibrationBtn'),
            viewCurrentPlotsBtn: document.getElementById('viewCurrentPlotsBtn'),

            // Modal
            plotsModal: document.getElementById('plotsModal'),
            plotsGrid: document.getElementById('plotsGrid'),
            downloadAllBtn: document.getElementById('downloadAllBtn'),

            // References
            referenceNameInput: document.getElementById('referenceNameInput'),
            referenceDescriptionInput: document.getElementById('referenceDescriptionInput'),
            createReferenceBtn: document.getElementById('createReferenceBtn'),
            referenceDropdown: document.getElementById('referenceDropdown'),
            setReferenceBtn: document.getElementById('setReferenceBtn'),
            clearReferenceBtn: document.getElementById('clearReferenceBtn'),
            deleteReferenceBtn: document.getElementById('deleteReferenceBtn'),
            previewReferenceBtn: document.getElementById('previewReferenceBtn'),
            currentReferenceInfo: document.getElementById('currentReferenceInfo'),
            currentReferenceName: document.getElementById('currentReferenceName'),
            currentReferenceTimestamp: document.getElementById('currentReferenceTimestamp'),
            currentReferenceDescription: document.getElementById('currentReferenceDescription'),
            currentReferenceCalibration: document.getElementById('currentReferenceCalibration'),

            // Laser controls
            laserManualMode: document.getElementById('laserManualMode'),
            laserTemp1: document.getElementById('laserTemp1'),
            laserTemp2: document.getElementById('laserTemp2'),
            laserCurrent1: document.getElementById('laserCurrent1'),
            laserCurrent2: document.getElementById('laserCurrent2'),
            laserMinCurrent1: document.getElementById('laserMinCurrent1'),
            laserMaxCurrent1: document.getElementById('laserMaxCurrent1'),
            laserDeltaCurrent1: document.getElementById('laserDeltaCurrent1'),
            laserScanTemp1: document.getElementById('laserScanTemp1'),
            laserScanTemp2: document.getElementById('laserScanTemp2'),
            laserScanCurrent2: document.getElementById('laserScanCurrent2'),
            laserDeltaTime: document.getElementById('laserDeltaTime'),
            laserTau: document.getElementById('laserTau'),
            laserStartBtn: document.getElementById('laserStartBtn'),
            laserStopBtn: document.getElementById('laserStopBtn'),

            // Status
            presetCount: document.getElementById('presetCount'),
            calibrationCount: document.getElementById('calibrationCount'),
            referenceCount: document.getElementById('referenceCount'),
            systemStatus: document.getElementById('systemStatus')
        };

        this.headerElements = {
            preset: document.getElementById('headerPresetSummary'),
            calibration: document.getElementById('headerCalibrationSummary'),
            reference: document.getElementById('headerReferenceSummary')
        };
    }

    initSubManagers() {
        this.presetManager.init(this.elements);
        this.calibrationManager.init(this.elements);
        this.referenceManager.init(this.elements);
        this.laserManager.init({
            manualMode: this.elements.laserManualMode,
            temp1: this.elements.laserTemp1,
            temp2: this.elements.laserTemp2,
            current1: this.elements.laserCurrent1,
            current2: this.elements.laserCurrent2,
            minCurrent1: this.elements.laserMinCurrent1,
            maxCurrent1: this.elements.laserMaxCurrent1,
            deltaCurrent1: this.elements.laserDeltaCurrent1,
            scanTemp1: this.elements.laserScanTemp1,
            scanTemp2: this.elements.laserScanTemp2,
            scanCurrent2: this.elements.laserScanCurrent2,
            deltaTime: this.elements.laserDeltaTime,
            tau: this.elements.laserTau,
            startBtn: this.elements.laserStartBtn,
            stopBtn: this.elements.laserStopBtn
        });

        // Setup callbacks
        this.presetManager.onPresetChanged = async () => {
            const status = await this.loadStatus();
            this.calibrationManager.reset();
            await this.calibrationManager.loadWorkingCalibration();
            await this.ensureCurrentPreset(status);
            this.updateReferenceSummary(this.referenceManager.getCurrentReference());
        };

        this.calibrationManager.onCalibrationSaved = async () => {
            const status = await this.loadStatus();
            await this.ensureCurrentPreset(status);
        };

        this.calibrationManager.onCalibrationSet = async () => {
            const status = await this.loadStatus();
            await this.ensureCurrentPreset(status);
        };

        this.referenceManager.onReferenceUpdated = (reference) => {
            this.updateReferenceSummary(reference);
        };

        this.referenceManager.onShowPlots = (plotData) => {
            this.showPlotsModal(plotData);
        };
    }

    setupEventHandlers() {
        this.elements.viewPlotsBtn?.addEventListener('click', this.handleViewPlots);
        this.elements.viewCurrentPlotsBtn?.addEventListener('click', this.handleViewCurrentPlots);
    }

    async loadInitialData() {
        await this.presetManager.loadPresets();
        const status = await this.loadStatus();
        await this.calibrationManager.loadWorkingCalibration();
        await this.ensureCurrentPreset(status);
    }

    async loadStatus() {
        try {
            const status = await apiGet(API.SETTINGS.STATUS);
            await this.updateStatusDisplay(status);
            return status;
        } catch (e) {
            console.error('Status load failed:', e);
            if (this.elements.systemStatus) {
                this.elements.systemStatus.textContent = 'Не подключено';
            }
            if (this.elements.referenceCount) {
                this.elements.referenceCount.textContent = '-';
            }
            this.notify(ERROR, 'Ошибка статуса', 'Не удалось получить текущее состояние системы');
            return null;
        }
    }

    async fetchCurrentPreset() {
        try {
            return await apiGet(API.SETTINGS.PRESET_CURRENT);
        } catch (e) {
            console.error('Current preset fetch failed:', e);
            return null;
        }
    }

    async ensureCurrentPreset(status) {
        let preset = this.presetManager.getCurrentPreset();
        if (preset) {
            return preset;
        }

        const fallbackPreset = status?.current_preset ?? await this.fetchCurrentPreset();
        if (!fallbackPreset) {
            return null;
        }

        this.presetManager.setCurrentPresetDirect(fallbackPreset);
        this.calibrationManager.setCurrentPreset(fallbackPreset);
        await this.referenceManager.setCurrentPreset(fallbackPreset);
        await this.calibrationManager.loadWorkingCalibration();

        if (!status && this.elements.systemStatus) {
            this.elements.systemStatus.textContent = 'Не подключено';
        }

        const effectiveStatus = {
            ...(status ?? { available_presets: 0, available_calibrations: 0, available_references: 0 }),
            current_preset: fallbackPreset,
            available_references: this.referenceManager?.availableReferences?.length ?? 0,
        };

        if (!status) {
            if (this.elements.presetCount) {
                this.elements.presetCount.textContent = effectiveStatus.available_presets ?? '-';
            }
            if (this.elements.calibrationCount) {
                this.elements.calibrationCount.textContent = effectiveStatus.available_calibrations ?? '-';
            }
            if (this.elements.referenceCount) {
                this.elements.referenceCount.textContent = effectiveStatus.available_references ?? '-';
            }
        }

        this.updateHeaderSummary(effectiveStatus);

        return fallbackPreset;
    }

    async updateStatusDisplay(status) {
        this.presetManager.updateStatus(status);
        this.calibrationManager.updateStatus(status);

        const preset = this.presetManager.getCurrentPreset();
        this.calibrationManager.setCurrentPreset(preset);
        await this.referenceManager.setCurrentPreset(preset);

        if (this.elements.presetCount) {
            this.elements.presetCount.textContent = status?.available_presets ?? '-';
        }
        if (this.elements.calibrationCount) {
            this.elements.calibrationCount.textContent = status?.available_calibrations ?? '-';
        }
        if (this.elements.referenceCount) {
            const count = typeof status?.available_references === 'number'
                ? status.available_references
                : this.referenceManager?.availableReferences?.length;
            this.elements.referenceCount.textContent = typeof count === 'number' ? count : '-';
        }
        this.updateHeaderSummary(status);
        this.updateReferenceSummary(this.referenceManager.getCurrentReference());
    }

    async handleViewPlots() {
        this.debouncer.debounce('view-plots', async () => {
            const name = this.elements.calibrationDropdown.value;
            const preset = this.presetManager.getCurrentPreset();
            if (!name || !preset) return;

            try {
                ButtonState.set(this.elements.viewPlotsBtn, { state: 'loading', icon: 'loader', text: 'Загрузка...' });

                const url = buildUrl(API.SETTINGS.CALIBRATION_STANDARDS_PLOTS(name), {
                    preset_filename: preset.filename
                });
                const plotsData = await apiGet(url);

                this.showPlotsModal(plotsData);
            } catch (e) {
                console.error('Load plots failed:', e);
                this.notify(ERROR, 'Ошибка графиков', 'Не удалось загрузить графики калибровки');
            } finally {
                ButtonState.set(this.elements.viewPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'Показать графики' });
            }
        }, TIMING.DEBOUNCE_CALIBRATION);
    }

    async handleViewCurrentPlots() {
        this.debouncer.debounce('view-current-plots', async () => {
            const working = this.calibrationManager.getWorkingCalibration();
            if (!working || !working.active) return;

            try {
                ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'loading', icon: 'loader', text: 'Загрузка...' });

                const plotsData = await apiGet(API.SETTINGS.WORKING_CALIBRATION_PLOTS);
                this.showPlotsModal(plotsData);
            } catch (e) {
                if (e.status === 404) {
                    this.notify(WARNING, 'Нет данных', 'Нет активной калибровки или стандартов для отображения');
                } else {
                    console.error('Load current plots failed:', e);
                    this.notify(ERROR, 'Ошибка графиков', 'Не удалось загрузить графики текущей калибровки');
                }
            } finally {
                ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'Графики текущей калибровки' });
            }
        }, TIMING.DEBOUNCE_CALIBRATION);
    }

    showPlotsModal(plotsData) {
        const modal = this.elements.plotsModal;
        if (!modal) return;

        this.currentPlotsData = plotsData;

        if (plotsData.reference_name) {
            this.renderReferencePlot(plotsData);
        } else {
            this.renderCalibrationPlots(plotsData.individual_plots, plotsData.preset);
        }

        const title = modal.querySelector('.modal__title');
        if (title) {
            if (plotsData.reference_name) {
                title.innerHTML = `
                    <span data-icon="target"></span>
                    ${plotsData.reference_name} - ${plotsData.preset.mode.toUpperCase()}
                `;
            } else {
                title.innerHTML = `
                    <span data-icon="bar-chart-3"></span>
                    ${plotsData.calibration_name} - ${plotsData.preset.mode.toUpperCase()} Standards
                `;
            }
            renderIcons(title);
        }

        this.setupModalCloseHandlers(modal);

        modal.classList.add('modal--active');
        document.body.style.overflow = 'hidden';
    }

    renderReferencePlot(plotsData) {
        const container = this.elements.plotsGrid;
        if (!container) return;

        container.innerHTML = '';

        if (!plotsData.plot || plotsData.plot.error) {
            container.innerHTML = '<div class="plot-error">Не удалось загрузить график эталона</div>';
            return;
        }

        const card = document.createElement('div');
        card.className = 'chart-card';
        card.innerHTML = `
            <div class="chart-card__header">
                <div class="chart-card__title">
                    <span data-icon="target" class="chart-card__icon"></span>
                    ${plotsData.reference_name}
                </div>
                <div class="chart-card__actions">
                    <button class="chart-card__action" data-action="fullscreen" title="На весь экран">
                        <span data-icon="expand"></span>
                    </button>
                    <button class="chart-card__action" data-action="download" title="Скачать">
                        <span data-icon="download"></span>
                    </button>
                </div>
            </div>
            <div class="chart-card__content">
                <div class="chart-card__plot" id="reference-plot"></div>
            </div>
            <div class="chart-card__meta">
                <div class="chart-card__timestamp">Дата: ${new Date(plotsData.timestamp).toLocaleString()}</div>
                <div class="chart-card__sweep">${plotsData.description || 'Эталон открытого пространства'}</div>
            </div>
        `;

        card.addEventListener('click', (e) => {
            const action = e.target.closest?.('[data-action]')?.dataset.action;
            if (!action) return;
            e.stopPropagation();

            const plotEl = card.querySelector('.chart-card__plot');
            if (action === 'fullscreen') this.toggleFullscreen(card);
            if (action === 'download') this.downloadReferencePlot(plotsData, plotEl);
        });

        container.appendChild(card);
        renderIcons(card);

        const plotEl = card.querySelector('.chart-card__plot');
        this.renderPlotly(plotEl, plotsData.plot, plotsData.reference_name);
    }

    renderCalibrationPlots(individualPlots, preset) {
        const container = this.elements.plotsGrid;
        if (!container) return;

        container.innerHTML = '';

        if (!individualPlots || !Object.keys(individualPlots).length) {
            container.innerHTML = '<div class="plot-error">Нет доступных графиков калибровки</div>';
            return;
        }

        Object.entries(individualPlots).forEach(([name, plot]) => {
            if (plot.error) {
                const err = document.createElement('div');
                err.className = 'chart-card';
                err.innerHTML = `
                    <div class="chart-card__header">
                        <div class="chart-card__title">
                            <span data-icon="alert-circle" class="chart-card__icon"></span>
                            ${name.toUpperCase()} Standard
                        </div>
                    </div>
                    <div class="chart-card__content">
                        <div class="plot-error">Error: ${plot.error}</div>
                    </div>
                `;
                renderIcons(err);
                container.appendChild(err);
                return;
            }

            const card = this.createCalibrationChartCard(name, plot, preset);
            container.appendChild(card);
        });

        renderIcons(container);
    }

    createCalibrationChartCard(standardName, plotConfig, preset) {
        const card = document.createElement('div');
        card.className = 'chart-card';
        card.dataset.standard = standardName;

        const title = `Стандарт ${standardName.toUpperCase()}`;

        card.innerHTML = `
            <div class="chart-card__header">
                <div class="chart-card__title">
                    <span data-icon="bar-chart-3" class="chart-card__icon"></span>
                    ${title}
                </div>
                <div class="chart-card__actions">
                    <button class="chart-card__action" data-action="fullscreen" title="На весь экран">
                        <span data-icon="expand"></span>
                    </button>
                    <button class="chart-card__action" data-action="download" title="Скачать">
                        <span data-icon="download"></span>
                    </button>
                </div>
            </div>
            <div class="chart-card__content">
                <div class="chart-card__plot" id="calibration-plot-${standardName}"></div>
            </div>
            <div class="chart-card__meta">
                <div class="chart-card__timestamp">Стандарт: ${standardName.toUpperCase()}</div>
                <div class="chart-card__sweep">Пресет: ${preset?.filename || 'Неизвестно'}</div>
            </div>
        `;

        card.addEventListener('click', (e) => {
            const action = e.target.closest?.('[data-action]')?.dataset.action;
            if (!action) return;
            e.stopPropagation();

            const plotEl = card.querySelector('.chart-card__plot');
            if (action === 'fullscreen') this.toggleFullscreen(card);
            if (action === 'download') this.downloadCalibrationStandard(standardName, plotEl);
        });

        const plotEl = card.querySelector('.chart-card__plot');
        this.renderPlotly(plotEl, plotConfig, title);
        renderIcons(card);

        return card;
    }

    renderPlotly(container, plotConfig, title) {
        if (!container || !plotConfig || plotConfig.error) {
            container.innerHTML = `<div class="plot-error">Не удалось загрузить график: ${plotConfig?.error || 'Неизвестная ошибка'}</div>`;
            return;
        }

        const layoutOverrides = {
            title: { text: title, font: { size: 16, color: '#f1f5f9' } },
            xaxis: {
                ...plotConfig.layout?.xaxis,
                gridcolor: '#334155',
                zerolinecolor: '#475569',
                color: '#cbd5e1',
                fixedrange: false
            },
            yaxis: {
                ...plotConfig.layout?.yaxis,
                gridcolor: '#334155',
                zerolinecolor: '#475569',
                color: '#cbd5e1',
                fixedrange: false
            }
        };

        const configOverrides = {
            toImageButtonOptions: {
                format: 'png',
                filename: `calibration-plot-${Date.now()}`,
                height: 600,
                width: 800,
                scale: 1
            }
        };

        createPlotlyPlot(container, plotConfig.data, layoutOverrides, configOverrides);
    }

    async toggleFullscreen(card) {
        const plot = card.querySelector('.chart-card__plot');
        await togglePlotlyFullscreen(card, plot);
    }

    setupModalCloseHandlers(modal) {
        modal.querySelectorAll('[data-modal-close]').forEach(el => {
            el.addEventListener('click', () => this.closePlotsModal());
        });

        const downloadAllBtn = modal.querySelector('#downloadAllBtn');
        if (downloadAllBtn) {
            downloadAllBtn.addEventListener('click', () =>
                this.debouncer.debounce('download-all', () => this.downloadAllCalibrationData(), TIMING.DEBOUNCE_DOWNLOAD)
            );
        }

        const escHandler = (e) => {
            if (e.key === 'Escape') {
                this.closePlotsModal();
                document.removeEventListener('keydown', escHandler);
            }
        };
        document.addEventListener('keydown', escHandler);
    }

    closePlotsModal() {
        const modal = this.elements.plotsModal;
        if (!modal) return;

        modal.classList.remove('modal--active');
        document.body.style.overflow = '';

        const containers = modal.querySelectorAll('[id^="calibration-plot-"]');
        containers.forEach(c => cleanupPlotly(c));

        this.currentPlotsData = null;
    }

    async downloadReferencePlot(plotsData, plotContainer) {
        try {
            const ts = new Date().toISOString().replace(/[:.]/g, '-');
            const base = `${plotsData.reference_name}_${ts}`;

            if (plotContainer) {
                await downloadPlotlyImage(plotContainer, `${base}_plot`);
            }

            const data = {
                reference_info: {
                    name: plotsData.reference_name,
                    timestamp: plotsData.timestamp,
                    description: plotsData.description,
                    preset: plotsData.preset
                },
                plot_data: plotsData.plot
            };
            downloadJSON(data, `${base}_data.json`);
        } catch (e) {
            console.error('Download reference failed:', e);
            this.notify(ERROR, 'Ошибка скачивания', 'Не удалось скачать данные эталона');
        }
    }

    async downloadCalibrationStandard(standardName, plotContainer) {
        try {
            const ts = new Date().toISOString().replace(/[:.]/g, '-');
            const calibrationName = this.currentPlotsData?.calibration_name || 'unknown';
            const base = `${calibrationName}_${standardName}_${ts}`;

            if (plotContainer) {
                await downloadPlotlyImage(plotContainer, `${base}_plot`);
            }

            const data = this.prepareCalibrationDownloadData(standardName);
            downloadJSON(data, `${base}_data.json`);
        } catch (e) {
            console.error('Download standard failed:', e);
            this.notify(ERROR, 'Ошибка скачивания', 'Не удалось скачать данные калибровки');
        }
    }

    async downloadAllCalibrationData() {
        if (!this.currentPlotsData) return;

        try {
            const ts = new Date().toISOString().replace(/[:.]/g, '-');
            const calibrationName = this.currentPlotsData.calibration_name || 'unknown';
            const base = `${calibrationName}_complete_${ts}`;

            const btn = this.elements.downloadAllBtn;
            if (btn) ButtonState.set(btn, { state: 'loading', icon: 'loader', text: 'Скачивание...' });

            const complete = {
                export_info: {
                    export_timestamp: new Date().toISOString(),
                    calibration_name: calibrationName,
                    preset: this.currentPlotsData.preset
                },
                standards_data: this.currentPlotsData.individual_plots
            };

            downloadJSON(complete, `${base}.json`);

            this.notify(SUCCESS, 'Полное скачивание завершено', `Полный набор данных калибровки сохранён для ${calibrationName}`);
        } catch (e) {
            console.error('Download all failed:', e);
            this.notify(ERROR, 'Ошибка скачивания', 'Не удалось скачать полный набор данных калибровки');
        } finally {
            const btn = this.elements.downloadAllBtn;
            if (btn) ButtonState.set(btn, { state: 'normal', icon: 'download-cloud', text: 'Скачать всё' });
        }
    }

    prepareCalibrationDownloadData(standardName) {
        if (!this.currentPlotsData) return null;
        const plot = this.currentPlotsData.individual_plots[standardName];
        return {
            calibration_info: {
                calibration_name: this.currentPlotsData.calibration_name,
                preset: this.currentPlotsData.preset,
                standard_name: standardName,
                download_timestamp: new Date().toISOString()
            },
            plot_data: plot
        };
    }

    async refresh() {
        if (!this.isInitialized) return;
        await this.loadInitialData();
    }

    destroy() {
        this.presetManager.destroy();
        this.calibrationManager.destroy();
        this.referenceManager.destroy();

        this.elements.viewPlotsBtn?.removeEventListener('click', this.handleViewPlots);
        this.elements.viewCurrentPlotsBtn?.removeEventListener('click', this.handleViewCurrentPlots);

        this.isInitialized = false;
        console.log('Settings Manager destroyed');
    }

    formatFrequency(value) {
        if (value === null || value === undefined) return null;
        const numeric = Number(value);
        if (!Number.isFinite(numeric)) return null;
        const abs = Math.abs(numeric);
        const units = [
            { divider: 1e9, suffix: 'ГГц' },
            { divider: 1e6, suffix: 'МГц' },
            { divider: 1e3, suffix: 'кГц' }
        ];

        for (const unit of units) {
            if (abs >= unit.divider) {
                const scaled = numeric / unit.divider;
                const formatted = scaled >= 10 ? scaled.toFixed(0) : scaled.toFixed(2);
                return `${formatted} ${unit.suffix}`;
            }
        }

        return `${numeric.toFixed(0)} Гц`;
    }

    formatPresetSummary(preset) {
        if (!preset) return 'Не выбран';

        const parts = [];
        if (preset.mode) {
            parts.push(preset.mode.toUpperCase());
        }

        const start = this.formatFrequency(preset.start_freq);
        const stop = this.formatFrequency(preset.stop_freq);
        if (start && stop) {
            parts.push(`${start} – ${stop}`);
        } else if (start || stop) {
            parts.push(start || stop);
        }

        if (preset.points) {
            parts.push(`${preset.points} точек`);
        }

        if (preset.bandwidth) {
            const bw = this.formatFrequency(preset.bandwidth);
            if (bw) parts.push(`ПП ${bw}`);
        }

        return parts.join(' • ') || 'Пресет настроен';
    }

    formatCalibrationSummary(status) {
        const active = status?.current_calibration;
        if (active?.calibration_name) {
            return `Активна • ${active.calibration_name}`;
        }

        const working = status?.working_calibration;
        if (working?.progress) {
            const missingCount = working.missing_standards?.length || 0;
            const missingText = missingCount ? ` • не хватает ${missingCount} стандартов` : '';
            return `В процессе • ${working.progress}${missingText}`;
        }

        return 'Не задано';
    }

    updateHeaderSummary(status) {
        if (!this.headerElements) return;
        const { preset, calibration } = this.headerElements;
        if (preset) {
            preset.textContent = this.formatPresetSummary(status?.current_preset);
        }
        if (calibration) {
            calibration.textContent = this.formatCalibrationSummary(status);
        }
    }

    updateReferenceSummary(reference) {
        const target = this.headerElements?.reference;
        if (!target) return;

        if (!reference) {
            target.textContent = 'Не снят';
            return;
        }

        const name = reference.name || 'Эталон';
        let timestampText = '';
        if (reference.timestamp) {
            const timestamp = new Date(reference.timestamp);
            if (!Number.isNaN(timestamp.getTime())) {
                timestampText = timestamp.toLocaleString(undefined, { dateStyle: 'short', timeStyle: 'short' });
            }
        }

        const summaryParts = ['Активен', name];
        if (timestampText) {
            summaryParts.push(timestampText);
        }
        target.textContent = summaryParts.join(' • ');
    }

    notify(type, title, message) {
        this.notifications?.show?.({ type, title, message });
    }
}
