import { api } from '../../../js/api.js';
import { escapeHtml, hideAlert, showAlert } from '../../../js/utils.js';

const APPLY_MODE_LABELS = {
    DEFAULT: 'применяется по умолчанию',
    WEEKDAY: 'применяется автоматически',
    MANUAL: 'применяется вручную'
};

const DAY_SHORT_LABELS = {
    1: 'Пн',
    2: 'Вт',
    3: 'Ср',
    4: 'Чт',
    5: 'Пт',
    6: 'Сб',
    7: 'Вс'
};

export async function initTimeSlotsSettings() {
    const scopeSelect = document.getElementById('time-slot-scope-select');
    const scopeSummary = document.getElementById('time-slot-scope-summary');
    const scopeOpenCreateButton = document.getElementById('time-slot-scope-open-create');
    const scopeModal = document.getElementById('time-slot-scope-modal');
    const scopeModalCloseButton = document.getElementById('time-slot-scope-modal-close');
    const scopeModalCancelButton = document.getElementById('time-slot-scope-modal-cancel');
    const scopeForm = document.getElementById('time-slot-scope-form');
    const scopeNameInput = document.getElementById('time-slot-scope-name');
    const scopeDeleteButton = document.getElementById('time-slot-scope-delete');

    const form = document.getElementById('time-slot-form');
    const title = document.getElementById('time-slot-form-title');
    const idInput = document.getElementById('time-slot-id');
    const orderInput = document.getElementById('time-slot-order');
    const startInput = document.getElementById('time-slot-start');
    const endInput = document.getElementById('time-slot-end');
    const durationInput = document.getElementById('time-slot-duration');
    const resetButton = document.getElementById('time-slot-reset');
    const refreshButton = document.getElementById('time-slots-refresh');
    const tbody = document.getElementById('time-slots-tbody');

    let scopes = [];
    let slots = [];
    let activeScopeId = null;

    scopeSelect?.addEventListener('change', () => {
        activeScopeId = Number(scopeSelect.value);
        resetForm();
        renderActiveScope();
    });
    scopeOpenCreateButton?.addEventListener('click', openScopeModal);
    scopeModalCloseButton?.addEventListener('click', closeScopeModal);
    scopeModalCancelButton?.addEventListener('click', closeScopeModal);
    scopeModal?.addEventListener('click', (event) => {
        if (event.target === scopeModal) closeScopeModal();
    });
    scopeModal?.addEventListener('keydown', (event) => {
        if (event.key === 'Escape') closeScopeModal();
    });
    scopeForm?.addEventListener('submit', createScope);
    scopeDeleteButton?.addEventListener('click', deleteActiveScope);
    form?.addEventListener('submit', saveSlot);
    resetButton?.addEventListener('click', resetForm);
    refreshButton?.addEventListener('click', loadAll);
    startInput?.addEventListener('change', calculateDuration);
    endInput?.addEventListener('change', calculateDuration);
    tbody?.addEventListener('click', handleSlotTableClick);

    await loadAll();

    async function loadAll() {
        tbody.innerHTML = '<tr><td colspan="5" class="loading-row">Загрузка...</td></tr>';
        hideAlert('time-slot-alert');
        try {
            [scopes, slots] = await Promise.all([
                api.get('/api/admin/time-slots/scopes'),
                api.get('/api/admin/time-slots')
            ]);
            if (!activeScopeId || !scopes.some(scope => scope.id === activeScopeId)) {
                activeScopeId = defaultScope()?.id || scopes[0]?.id || null;
            }
            render();
        } catch (error) {
            tbody.innerHTML = `<tr><td colspan="5" class="loading-row">Ошибка загрузки: ${escapeHtml(error.message)}</td></tr>`;
        }
    }

    function render() {
        renderScopeSelects();
        renderActiveScope();
    }

    function renderActiveScope() {
        updateScopeActions();
        renderScopeSummary();
        renderSlots();
    }

    function renderScopeSelects() {
        scopeSelect.innerHTML = scopes.map(scope => `
            <option value="${scope.id}">${escapeHtml(scopeOptionLabel(scope))}</option>
        `).join('');
        scopeSelect.value = activeScopeId ? String(activeScopeId) : '';

        updateScopeActions();
    }

    function updateScopeActions() {
        const activeScope = selectedScope();
        scopeDeleteButton.disabled = !activeScope || activeScope.systemScope;
    }

    function renderScopeSummary() {
        const scope = selectedScope();
        if (!scope) {
            scopeSummary.innerHTML = '<span class="muted">Сетки времени не настроены</span>';
            return;
        }

        const mode = APPLY_MODE_LABELS[scope.applyMode] || scope.applyMode;
        const day = scope.applyMode === 'WEEKDAY' ? `, ${dayShort(scope.dayOfWeek)}` : '';
        const slotCount = slots.filter(slot => slot.scopeId === scope.id).length;
        scopeSummary.innerHTML = `
            <span class="scope-badge ${scope.applyMode === 'DEFAULT' ? 'scope-badge-base' : ''}">${escapeHtml(scopeBadgeLabel(scope))}</span>
            <span>${escapeHtml(mode + day)}. Слотов: ${slotCount}.</span>
        `;
    }

    function renderSlots() {
        const scopeSlots = slots
            .filter(slot => slot.scopeId === activeScopeId)
            .sort((a, b) => (a.orderNumber || 0) - (b.orderNumber || 0));

        if (!scopeSlots.length) {
            tbody.innerHTML = '<tr><td colspan="5" class="loading-row">В выбранной сетке нет слотов</td></tr>';
            return;
        }

        tbody.innerHTML = scopeSlots.map(slot => `
            <tr>
                <td>${escapeHtml(String(slot.orderNumber ?? '-'))}</td>
                <td>${escapeHtml(trimTime(slot.startTime))}</td>
                <td>${escapeHtml(trimTime(slot.endTime))}</td>
                <td>${escapeHtml(String(slot.durationMinutes ?? '-'))}</td>
                <td class="actions-cell">
                    <button type="button" class="btn btn-sm btn-secondary btn-edit-time-slot" data-id="${slot.id}">Изменить</button>
                    <button type="button" class="btn btn-sm btn-danger btn-delete-time-slot" data-id="${slot.id}">Удалить</button>
                </td>
            </tr>
        `).join('');
    }

    function openScopeModal() {
        scopeForm.reset();
        hideAlert('time-slot-scope-alert');
        scopeModal.classList.add('open');
        scopeModal.setAttribute('aria-hidden', 'false');
        window.setTimeout(() => scopeNameInput?.focus(), 0);
    }

    function closeScopeModal() {
        scopeModal.classList.remove('open');
        scopeModal.setAttribute('aria-hidden', 'true');
        hideAlert('time-slot-scope-alert');
    }

    async function createScope(event) {
        event.preventDefault();
        const name = scopeNameInput.value.trim();
        if (!name) {
            showAlert('time-slot-scope-alert', 'Введите название ручной сетки', 'error');
            return;
        }
        try {
            const saved = await api.post('/api/admin/time-slots/scopes', { name });
            activeScopeId = saved.id;
            closeScopeModal();
            showAlert('time-slot-alert', 'Сетка времени создана', 'success');
            await loadAll();
        } catch (error) {
            showAlert('time-slot-scope-alert', error.message || 'Ошибка создания сетки времени', 'error');
        }
    }

    async function deleteActiveScope() {
        const scope = selectedScope();
        if (!scope || scope.systemScope) return;
        if (!confirm(`Удалить сетку "${scope.name}" вместе с её слотами и ручными назначениями?`)) return;
        try {
            await api.delete('/api/admin/time-slots/scopes/' + scope.id);
            activeScopeId = defaultScope()?.id || null;
            resetForm();
            showAlert('time-slot-alert', 'Сетка времени удалена', 'success');
            await loadAll();
        } catch (error) {
            showAlert('time-slot-alert', error.message || 'Ошибка удаления сетки времени', 'error');
        }
    }

    async function saveSlot(event) {
        event.preventDefault();
        hideAlert('time-slot-alert');

        const payload = {
            id: idInput.value ? Number(idInput.value) : null,
            orderNumber: Number(orderInput.value),
            scopeId: activeScopeId,
            startTime: startInput.value,
            endTime: endInput.value
        };

        try {
            validateSlotPayload(payload);
            const id = idInput.value;
            await (id
                ? api.put('/api/admin/time-slots/' + id, payload)
                : api.post('/api/admin/time-slots', payload));
            showAlert('time-slot-alert', 'Временной слот сохранён', 'success');
            resetForm();
            await loadAll();
        } catch (error) {
            showAlert('time-slot-alert', error.message || 'Ошибка сохранения временного слота', 'error');
        }
    }

    async function handleSlotTableClick(event) {
        const editButton = event.target.closest('.btn-edit-time-slot');
        const deleteButton = event.target.closest('.btn-delete-time-slot');

        if (editButton) {
            const slot = slots.find(item => String(item.id) === String(editButton.dataset.id));
            if (!slot) return;
            activeScopeId = slot.scopeId;
            title.textContent = 'Редактирование слота';
            idInput.value = slot.id;
            orderInput.value = slot.orderNumber || '';
            startInput.value = trimTime(slot.startTime);
            endInput.value = trimTime(slot.endTime);
            durationInput.value = slot.durationMinutes || '';
            hideAlert('time-slot-alert');
            render();
            form.scrollIntoView({ behavior: 'smooth', block: 'start' });
            return;
        }

        if (deleteButton) {
            if (!confirm('Удалить временной слот?')) return;
            try {
                await api.delete('/api/admin/time-slots/' + deleteButton.dataset.id);
                showAlert('time-slot-alert', 'Временной слот удалён', 'success');
                resetForm();
                await loadAll();
            } catch (error) {
                showAlert('time-slot-alert', error.message || 'Ошибка удаления временного слота', 'error');
            }
        }
    }

    function validateSlotPayload(payload) {
        if (!payload.scopeId) {
            throw new Error('Выберите сетку времени');
        }
        if (!payload.orderNumber || payload.orderNumber <= 0) {
            throw new Error('Укажите номер пары');
        }
        if (!payload.startTime || !payload.endTime) {
            throw new Error('Укажите время начала и окончания');
        }
        if (payload.startTime >= payload.endTime) {
            throw new Error('Время начала должно быть раньше времени окончания');
        }
    }

    function calculateDuration() {
        durationInput.value = '';
        if (!startInput.value || !endInput.value || startInput.value >= endInput.value) return;
        const [startHour, startMinute] = startInput.value.split(':').map(Number);
        const [endHour, endMinute] = endInput.value.split(':').map(Number);
        durationInput.value = String((endHour * 60 + endMinute) - (startHour * 60 + startMinute));
    }

    function resetForm() {
        form.reset();
        idInput.value = '';
        title.textContent = 'Новый слот';
        hideAlert('time-slot-alert');
    }

    function selectedScope() {
        return scopes.find(scope => scope.id === activeScopeId) || null;
    }

    function defaultScope() {
        return scopes.find(scope => scope.applyMode === 'DEFAULT') || null;
    }
}

function scopeOptionLabel(scope) {
    const suffix = scope.applyMode === 'WEEKDAY'
        ? `, ${dayShort(scope.dayOfWeek)}`
        : '';
    return `${scope.name} - ${APPLY_MODE_LABELS[scope.applyMode] || scope.applyMode}${suffix}`;
}

function scopeBadgeLabel(scope) {
    if (scope.applyMode === 'DEFAULT') return 'Базовая';
    if (scope.applyMode === 'WEEKDAY') return dayShort(scope.dayOfWeek);
    return 'Ручная';
}

function dayShort(dayOfWeek) {
    return DAY_SHORT_LABELS[Number(dayOfWeek)] || '-';
}

function trimTime(value) {
    return value ? String(value).slice(0, 5) : '';
}
