/**
 * Laser Manager
 * Handles laser control interface with two modes: manual and scan
 */

import { apiPost } from '../api-client.js';
import { API, NOTIFICATION_TYPES } from '../constants.js';

const { SUCCESS, ERROR } = NOTIFICATION_TYPES;

export class LaserManager {
    constructor(notifications) {
        this.notifications = notifications;
        this.elements = {};
        this.isRunning = false;
        this.isManualMode = false;

        // Bind methods
        this.handleModeChange = this.handleModeChange.bind(this);
        this.handleStartClick = this.handleStartClick.bind(this);
        this.handleStopClick = this.handleStopClick.bind(this);
    }

    init(elements) {
        this.elements = elements;

        // Add event listeners
        this.elements.manualMode?.addEventListener('change', this.handleModeChange);
        this.elements.startBtn?.addEventListener('click', this.handleStartClick);
        this.elements.stopBtn?.addEventListener('click', this.handleStopClick);

        // Initialize UI state
        this.updateUIState();
    }

    destroy() {
        this.elements.manualMode?.removeEventListener('change', this.handleModeChange);
        this.elements.startBtn?.removeEventListener('click', this.handleStartClick);
        this.elements.stopBtn?.removeEventListener('click', this.handleStopClick);
    }

    handleModeChange() {
        this.isManualMode = this.elements.manualMode?.checked || false;
        this.updateUIState();
    }

    updateUIState() {
        const manualSection = document.getElementById('laserManualSection');
        const scanSection = document.getElementById('laserScanSection');

        if (this.isManualMode) {
            // Manual mode: show manual controls, hide scan controls
            if (manualSection) manualSection.style.display = 'block';
            if (scanSection) scanSection.style.display = 'none';

            // Enable manual mode inputs only if not running
            if (!this.isRunning) {
                this.elements.temp1.disabled = false;
                this.elements.temp2.disabled = false;
                this.elements.current1.disabled = false;
                this.elements.current2.disabled = false;
            }

            // Disable scan inputs
            this.elements.minCurrent1.disabled = true;
            this.elements.maxCurrent1.disabled = true;
            this.elements.deltaCurrent1.disabled = true;
            this.elements.scanTemp1.disabled = true;
            this.elements.scanTemp2.disabled = true;
            this.elements.scanCurrent2.disabled = true;
            this.elements.deltaTime.disabled = true;
            this.elements.tau.disabled = true;
        } else {
            // Scan mode: hide manual controls, show scan controls
            if (manualSection) manualSection.style.display = 'none';
            if (scanSection) scanSection.style.display = 'block';

            // Disable manual mode inputs
            this.elements.temp1.disabled = true;
            this.elements.temp2.disabled = true;
            this.elements.current1.disabled = true;
            this.elements.current2.disabled = true;

            // Enable scan inputs only if not running
            if (!this.isRunning) {
                this.elements.minCurrent1.disabled = false;
                this.elements.maxCurrent1.disabled = false;
                this.elements.deltaCurrent1.disabled = false;
                this.elements.scanTemp1.disabled = false;
                this.elements.scanTemp2.disabled = false;
                this.elements.scanCurrent2.disabled = false;
                this.elements.deltaTime.disabled = false;
                this.elements.tau.disabled = false;
            }
        }

        // Enable/disable start button based on running state
        if (this.elements.startBtn) {
            this.elements.startBtn.disabled = this.isRunning;
        }
        if (this.elements.stopBtn) {
            this.elements.stopBtn.disabled = !this.isRunning;
        }
    }

    async handleStartClick() {
        if (this.isRunning) {
            this.notify(ERROR, 'Ошибка', 'Цикл уже запущен');
            return;
        }

        try {
            // Disable start button during request
            this.elements.startBtn.disabled = true;

            let parameters;
            let endpoint;

            if (this.isManualMode) {
                // Manual mode - use simplified endpoint with only t1, t2, i1, i2
                parameters = this.collectManualParametersSimple();
                endpoint = API.LASER.START_MANUAL;
            } else {
                // Scan mode - use full endpoint with scan parameters
                parameters = this.collectScanParameters();
                endpoint = API.LASER.START;
            }

            // Validate parameters
            if (!this.validateParameters(parameters)) {
                this.elements.startBtn.disabled = false;
                return;
            }

            // Send start request to appropriate endpoint
            const response = await apiPost(endpoint, parameters);

            if (response.success) {
                this.isRunning = true;
                this.notify(SUCCESS, 'Успешно', response.message);

                // Disable all controls during operation
                this.disableAllControls();

                // Update button states
                this.elements.startBtn.disabled = true;
                this.elements.stopBtn.disabled = false;

                console.log('Laser cycle started:', parameters);
            } else {
                this.notify(ERROR, 'Ошибка', response.message);
                this.elements.startBtn.disabled = false;
            }

        } catch (error) {
            console.error('Failed to start laser cycle:', error);
            this.notify(ERROR, 'Ошибка', `Не удалось запустить цикл: ${error.message}`);
            this.elements.startBtn.disabled = false;
        }
    }

    async handleStopClick() {
        if (!this.isRunning) {
            this.notify(ERROR, 'Ошибка', 'Цикл не запущен');
            return;
        }

        try {
            // Disable stop button during request
            this.elements.stopBtn.disabled = true;

            const response = await apiPost(API.LASER.STOP, {});

            if (response.success) {
                this.isRunning = false;
                this.notify(SUCCESS, 'Успешно', response.message);

                // Re-enable controls
                this.enableAllControls();
                this.updateUIState();

                console.log('Laser cycle stopped');
            } else {
                this.notify(ERROR, 'Ошибка', response.message);
                this.elements.stopBtn.disabled = false;
            }

        } catch (error) {
            console.error('Failed to stop laser cycle:', error);
            this.notify(ERROR, 'Ошибка', `Не удалось остановить цикл: ${error.message}`);
            this.elements.stopBtn.disabled = false;
        }
    }

    collectManualParameters() {
        // Manual mode: use fixed temperature and current values
        // Set min=max to indicate manual mode
        const temp1 = parseFloat(this.elements.temp1.value);
        const temp2 = parseFloat(this.elements.temp2.value);
        const current1 = parseFloat(this.elements.current1.value);
        const current2 = parseFloat(this.elements.current2.value);

        return {
            // Manual mode indicated by setting enable_c1 = false and all ranges equal
            enable_c1: false,
            enable_t1: false,
            enable_t2: false,
            enable_c2: false,

            // Temperature values (same for min/max in manual mode)
            min_temp_1: temp1,
            max_temp_1: temp1,
            delta_temp_1: 0.05,
            min_temp_2: temp2,
            max_temp_2: temp2,
            delta_temp_2: 0.05,

            // Current values (same for min/max in manual mode)
            min_current_1: current1,
            max_current_1: current1,
            delta_current_1: 0.05,
            min_current_2: current2,
            max_current_2: current2,
            delta_current_2: 0.05,

            // Time parameters (not used in manual mode but required)
            delta_time: 50,
            tau: 10
        };
    }

    collectManualParametersSimple() {
        // Simplified manual mode: only 4 parameters (t1, t2, i1, i2)
        return {
            t1: parseFloat(this.elements.temp1.value),
            t2: parseFloat(this.elements.temp2.value),
            i1: parseFloat(this.elements.current1.value),
            i2: parseFloat(this.elements.current2.value)
        };
    }

    collectScanParameters() {
        // Scan mode: scan current 1 while keeping other parameters fixed
        return {
            enable_c1: true,  // Scanning current 1
            enable_t1: false,
            enable_t2: false,
            enable_c2: false,

            // Temperature 1 (fixed)
            min_temp_1: parseFloat(this.elements.scanTemp1.value),
            max_temp_1: parseFloat(this.elements.scanTemp1.value),
            delta_temp_1: 0.05,

            // Temperature 2 (fixed)
            min_temp_2: parseFloat(this.elements.scanTemp2.value),
            max_temp_2: parseFloat(this.elements.scanTemp2.value),
            delta_temp_2: 0.05,

            // Current 1 (scanning range)
            min_current_1: parseFloat(this.elements.minCurrent1.value),
            max_current_1: parseFloat(this.elements.maxCurrent1.value),
            delta_current_1: parseFloat(this.elements.deltaCurrent1.value),

            // Current 2 (fixed)
            min_current_2: parseFloat(this.elements.scanCurrent2.value),
            max_current_2: parseFloat(this.elements.scanCurrent2.value),
            delta_current_2: 0.05,

            // Time parameters
            delta_time: parseInt(this.elements.deltaTime.value),
            tau: parseInt(this.elements.tau.value)
        };
    }

    validateParameters(params) {
        // Check if simplified format (t1, t2, i1, i2)
        if ('t1' in params && 't2' in params && 'i1' in params && 'i2' in params) {
            // Simplified format validation
            const values = [params.t1, params.t2, params.i1, params.i2];

            if (values.some(v => isNaN(v))) {
                this.notify(ERROR, 'Ошибка валидации', 'Все поля должны быть заполнены корректными числами');
                return false;
            }

            // Check temperature ranges
            if (params.t1 < -1 || params.t1 > 45 || params.t2 < -1 || params.t2 > 45) {
                this.notify(ERROR, 'Ошибка валидации', 'Температура должна быть от -1 до 45°C');
                return false;
            }

            // Check current ranges
            if (params.i1 < 15 || params.i1 > 70 || params.i2 < 15 || params.i2 > 60) {
                this.notify(ERROR, 'Ошибка валидации', 'Ток лазера 1: 15-70мА, лазера 2: 15-60мА');
                return false;
            }

            return true;
        }

        // Full format validation (original)
        // Check for NaN values
        const values = [
            params.min_temp_1, params.max_temp_1,
            params.min_temp_2, params.max_temp_2,
            params.min_current_1, params.max_current_1,
            params.min_current_2, params.max_current_2,
            params.delta_time, params.tau
        ];

        if (values.some(v => isNaN(v))) {
            this.notify(ERROR, 'Ошибка валидации', 'Все поля должны быть заполнены корректными числами');
            return false;
        }

        // Check temperature ranges
        if (params.min_temp_1 < -1 || params.min_temp_1 > 45 ||
            params.max_temp_1 < -1 || params.max_temp_1 > 45 ||
            params.min_temp_2 < -1 || params.min_temp_2 > 45 ||
            params.max_temp_2 < -1 || params.max_temp_2 > 45) {
            this.notify(ERROR, 'Ошибка валидации', 'Температура должна быть от -1 до 45°C');
            return false;
        }

        // Check current ranges
        if (params.min_current_1 < 15 || params.max_current_1 > 70 ||
            params.min_current_2 < 15 || params.max_current_2 > 60) {
            this.notify(ERROR, 'Ошибка валидации', 'Ток должен быть в допустимых пределах');
            return false;
        }

        // In scan mode, check min < max for current 1
        if (!this.isManualMode) {
            if (params.min_current_1 >= params.max_current_1) {
                this.notify(ERROR, 'Ошибка валидации',
                    'Минимальный ток лазера 1 должен быть меньше максимального');
                return false;
            }

            // Check delta_time is multiple of 10
            if (params.delta_time % 10 !== 0) {
                this.notify(ERROR, 'Ошибка валидации',
                    'Шаг дискретизации времени должен быть кратен 10 мкс');
                return false;
            }

            // Check time parameters
            if (params.delta_time < 20 || params.delta_time > 100) {
                this.notify(ERROR, 'Ошибка валидации',
                    'Шаг дискретизации времени должен быть от 20 до 100 мкс');
                return false;
            }

            if (params.tau < 3 || params.tau > 10) {
                this.notify(ERROR, 'Ошибка валидации',
                    'Время задержки должно быть от 3 до 10 мс');
                return false;
            }
        }

        return true;
    }

    disableAllControls() {
        // Disable mode checkbox
        if (this.elements.manualMode) {
            this.elements.manualMode.disabled = true;
        }

        // Disable all input fields
        const allInputs = [
            this.elements.temp1,
            this.elements.temp2,
            this.elements.current1,
            this.elements.current2,
            this.elements.minCurrent1,
            this.elements.maxCurrent1,
            this.elements.deltaCurrent1,
            this.elements.scanTemp1,
            this.elements.scanTemp2,
            this.elements.scanCurrent2,
            this.elements.deltaTime,
            this.elements.tau
        ];

        allInputs.forEach(input => {
            if (input) input.disabled = true;
        });
    }

    enableAllControls() {
        // Enable mode checkbox
        if (this.elements.manualMode) {
            this.elements.manualMode.disabled = false;
        }

        // UI state will be updated by updateUIState() call after this
    }

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