import { api } from '../api.js';
import { escapeHtml } from '../utils.js';
import {
    CONFLICT_CHECK_STATE,
    conflictCheckPresentation,
    currentWeekDateRange,
    formatLocalDate,
    loadDepartmentSchedules
} from '../dashboard-conflicts.js';

export async function initDashboard() {
    // DOM Элементы
    const metricGroups = document.getElementById('metric-groups');
    const metricStudents = document.getElementById('metric-students');
    const metricTeachers = document.getElementById('metric-teachers');
    const metricClassrooms = document.getElementById('metric-classrooms');

    const currentTimeSlot = document.getElementById('current-time-slot');
    const currentLessonsTbody = document.getElementById('current-lessons-tbody');
    const freeClassroomsList = document.getElementById('free-classrooms-list');
    const conflictsContainer = document.getElementById('conflicts-container');
    const btnRecheck = document.getElementById('btn-recheck-conflicts');

    let departments = [];
    let classrooms = [];
    let groups = [];
    let teachers = [];
    let todayLessons = [];
    let timeSlots = [];
    let dashboardDataReady = false;

    btnRecheck.addEventListener('click', async () => {
        btnRecheck.disabled = true;
        btnRecheck.setAttribute('aria-busy', 'true');
        btnRecheck.textContent = 'Проверка…';
        try {
            if (dashboardDataReady) {
                await checkConflicts();
            } else {
                await loadData();
            }
        } finally {
            btnRecheck.textContent = 'Перепроверить';
            btnRecheck.disabled = false;
            btnRecheck.removeAttribute('aria-busy');
        }
    });

    async function loadData() {
        dashboardDataReady = false;
        try {
            // Загружаем базовые справочники
            [departments, classrooms, groups, teachers] = await Promise.all([
                api.get('/api/departments'),
                api.get('/api/classrooms?includeArchived=false'),
                api.get('/api/groups?includeArchived=false'),
                api.get('/api/users/teachers')
            ]);

            // Выводим метрики
            metricGroups.textContent = groups.length;
            const totalStudents = groups.reduce((acc, g) => acc + (g.groupSize || 0), 0);
            metricStudents.textContent = totalStudents;
            metricTeachers.textContent = teachers.length;

            const todayStr = formatLocalDate(new Date());

            // Загружаем временные слоты и сегодняшнее расписание
            const lessonsPromises = departments.map(d => 
                api.get(`/api/schedule/search?departmentId=${d.id}&startDate=${todayStr}&endDate=${todayStr}`).catch(() => [])
            );
            const lessonsArrays = await Promise.all(lessonsPromises);
            todayLessons = lessonsArrays.flat();

            try {
                timeSlots = await api.get(`/api/admin/time-slots/effective?date=${todayStr}`);
            } catch (e) {
                // Если эндпоинт effective не поддерживается, используем базовые слоты
                const baseSlots = await api.get('/api/admin/time-slots').catch(() => []);
                // Отфильтруем базовые слоты тенанта (scopeId = DEFAULT или аналогично)
                timeSlots = baseSlots.filter(s => s.scopeId === 1 || !s.scopeId);
            }

            // Сортируем слоты по времени
            timeSlots.sort((a, b) => (a.orderNumber || 0) - (b.orderNumber || 0));

            // Посчитаем занятость аудиторий сегодня
            const occupiedClassroomIds = new Set(todayLessons.map(l => l.classroomId).filter(Boolean));
            const activeClassrooms = classrooms.filter(c => c.isAvailable && c.status !== 'ARCHIVED');
            const classPercent = activeClassrooms.length 
                ? Math.round((occupiedClassroomIds.size / activeClassrooms.length) * 100)
                : 0;
            metricClassrooms.textContent = `${classPercent}% (${occupiedClassroomIds.size}/${activeClassrooms.length})`;

            updateRealtimeMonitoring();
            dashboardDataReady = true;
            await checkConflicts();
        } catch (e) {
            dashboardDataReady = false;
            console.error('Не удалось загрузить данные панели', {
                errorType: e?.name || 'Error'
            });
            conflictsContainer.innerHTML = renderCheckStateCard({
                tone: 'error',
                title: 'Проверка не выполнена',
                description: 'Не удалось загрузить данные панели. Нажмите «Перепроверить», чтобы повторить попытку.'
            });
        }
    }

    function updateRealtimeMonitoring() {
        const now = new Date();
        const currentTimeStr = now.toTimeString().split(' ')[0]; // HH:MM:SS
        
        // Находим текущий временной слот
        let currentSlot = null;
        for (const slot of timeSlots) {
            if (currentTimeStr >= slot.startTime && currentTimeStr <= slot.endTime) {
                currentSlot = slot;
                break;
            }
        }

        if (currentSlot) {
            currentTimeSlot.textContent = `Пара №${currentSlot.orderNumber} (${currentSlot.startTime.substring(0, 5)} – ${currentSlot.endTime.substring(0, 5)})`;
            renderCurrentLessons(currentSlot.orderNumber);
            renderFreeClassrooms(currentSlot.orderNumber);
        } else {
            currentTimeSlot.textContent = 'Вне сетки пар';
            currentLessonsTbody.innerHTML = '<tr><td colspan="4" class="loading-row" style="padding: 1.5rem; text-align: center; color: var(--text-secondary);">В данный момент учебные пары не проводятся</td></tr>';
            
            // Если сейчас нет пары, покажем свободные аудитории на ближайшую следующую пару (или просто все свободные)
            renderFreeClassrooms(null);
        }
    }

    function renderCurrentLessons(slotOrder) {
        const activeLessons = todayLessons.filter(l => l.timeSlotOrder === slotOrder);
        if (!activeLessons.length) {
            currentLessonsTbody.innerHTML = '<tr><td colspan="4" class="loading-row" style="padding: 1.5rem; text-align: center; color: var(--text-secondary);">В текущий слот занятий не запланировано</td></tr>';
            return;
        }

        currentLessonsTbody.innerHTML = activeLessons.map(l => `
            <tr>
                <td style="padding: 0.75rem;"><strong>${escapeHtml(l.classroomName)}</strong></td>
                <td style="padding: 0.75rem;">${escapeHtml(l.subjectName)} <span class="badge badge-ef" style="font-size:0.75rem;">${escapeHtml(l.lessonTypeName)}</span></td>
                <td style="padding: 0.75rem;">${escapeHtml(l.teacherName)}</td>
                <td style="padding: 0.75rem;"><span class="badge badge-available">${escapeHtml(l.groupNames.join(', '))}</span></td>
            </tr>
        `).join('');
    }

    function renderFreeClassrooms(slotOrder) {
        const activeClassrooms = classrooms.filter(c => c.isAvailable && c.status !== 'ARCHIVED');
        let occupiedIds = new Set();
        if (slotOrder !== null) {
            occupiedIds = new Set(todayLessons.filter(l => l.timeSlotOrder === slotOrder).map(l => l.classroomId));
        }

        const free = activeClassrooms.filter(c => !occupiedIds.has(c.id));
        if (!free.length) {
            freeClassroomsList.innerHTML = '<span style="color: var(--error); font-size: 0.9rem; font-weight: 500;">Все аудитории заняты</span>';
            return;
        }

        freeClassroomsList.innerHTML = free.map(c => `
            <span class="badge badge-available" style="padding: 0.4rem 0.6rem; font-size: 0.85rem; background: rgba(16, 185, 129, 0.1); color: #10b981; border: 1px solid rgba(16, 185, 129, 0.2);">
                ${escapeHtml(c.name)} (${c.capacity} м.)
            </span>
        `).join('');
    }

    // --- Анализ конфликтов (Red Zone) ---
    async function checkConflicts() {
        conflictsContainer.setAttribute('aria-busy', 'true');
        conflictsContainer.innerHTML = '<div class="loading-row" style="text-align: center; padding: 2rem; color: var(--text-secondary);">Анализ расписания и выявление конфликтов...</div>';

        try {
            const { startDate, endDate } = currentWeekDateRange(new Date());
            const scheduleLoad = await loadDepartmentSchedules(
                departments,
                department => api.get(
                    `/api/schedule/search?departmentId=${department.id}`
                    + `&startDate=${startDate}&endDate=${endDate}`
                )
            );

            if (scheduleLoad.state === CONFLICT_CHECK_STATE.NOT_RUN) {
                renderConflicts([], scheduleLoad, { startDate, endDate });
                return;
            }

            const weekLessons = scheduleLoad.lessons;

            const conflicts = [];

            // Мапы для быстрого поиска характеристик групп и аудиторий
            const groupSizeMap = new Map(groups.map(g => [g.id, g.groupSize || 0]));
            const classroomCapacityMap = new Map(classrooms.map(c => [c.id, c.capacity || 0]));

            // 1. Проверка накладок преподавателей
            // Ключ: date + '_' + timeSlotOrder + '_' + teacherId
            const teacherSlots = new Map();
            weekLessons.forEach(l => {
                if (!l.teacherId) return;
                const key = `${l.date}_${l.timeSlotOrder}_${l.teacherId}`;
                if (!teacherSlots.has(key)) {
                    teacherSlots.set(key, []);
                }
                teacherSlots.get(key).push(l);
            });

            teacherSlots.forEach((lessons, key) => {
                if (lessons.length > 1) {
                    // Проверим, если все занятия в одной аудитории — это потоковая лекция, а не конфликт
                    const classroomIds = new Set(lessons.map(l => l.classroomId));
                    if (classroomIds.size > 1) {
                        const first = lessons[0];
                        const listStr = lessons.map(l => `ауд. ${l.classroomName} (группа ${l.groupNames.join(', ')})`).join(', ');
                        conflicts.push({
                            type: 'TEACHER_COLLISION',
                            title: 'Накладка в расписании преподавателя',
                            description: `Преподаватель <strong>${escapeHtml(first.teacherName)}</strong> назначен одновременно в разные места: ${escapeHtml(listStr)} на <strong>${first.date} (${first.dayName}), пара №${first.timeSlotOrder}</strong>.`,
                            severity: 'error'
                        });
                    }
                }
            });

            // 2. Проверка накладок аудиторий
            // Ключ: date + '_' + timeSlotOrder + '_' + classroomId
            const classroomSlots = new Map();
            weekLessons.forEach(l => {
                if (!l.classroomId) return;
                const key = `${l.date}_${l.timeSlotOrder}_${l.classroomId}`;
                if (!classroomSlots.has(key)) {
                    classroomSlots.set(key, []);
                }
                classroomSlots.get(key).push(l);
            });

            classroomSlots.forEach((lessons, key) => {
                if (lessons.length > 1) {
                    // Проверим, не является ли это потоковой лекцией (один преподаватель и одна дисциплина)
                    const teacherIds = new Set(lessons.map(l => l.teacherId));
                    const subjectIds = new Set(lessons.map(l => l.subjectId));
                    
                    if (teacherIds.size > 1 || subjectIds.size > 1) {
                        const first = lessons[0];
                        const details = lessons.map(l => `препод. ${l.teacherName} (предмет: ${l.subjectName}, группа: ${l.groupNames.join(', ')})`).join(' И ');
                        conflicts.push({
                            type: 'CLASSROOM_COLLISION',
                            title: 'Накладка в аудитории',
                            description: `Аудитория <strong>${escapeHtml(first.classroomName)}</strong> занята одновременно разными занятиями: ${escapeHtml(details)} на <strong>${first.date} (${first.dayName}), пара №${first.timeSlotOrder}</strong>.`,
                            severity: 'error'
                        });
                    }
                }
            });

            // 3. Проверка превышения вместимости аудитории
            // Считаем сумму студентов для каждого уникального занятия в аудитории
            classroomSlots.forEach((lessons, key) => {
                if (!lessons.length) return;
                const first = lessons[0];
                const capacity = classroomCapacityMap.get(first.classroomId) || 0;
                
                // Суммируем численность всех групп, назначенных на этот слот в этой аудитории
                const groupIds = new Set();
                lessons.forEach(l => {
                    if (l.groupIds) {
                        l.groupIds.forEach(id => groupIds.add(id));
                    }
                });

                let totalStudents = 0;
                groupIds.forEach(id => {
                    totalStudents += groupSizeMap.get(id) || 0;
                });

                if (totalStudents > capacity) {
                    const groupNamesList = lessons.map(l => l.groupNames.join(', ')).join(', ');
                    conflicts.push({
                        type: 'CAPACITY_OVERFLOW',
                        title: 'Превышение вместимости аудитории',
                        description: `Вместимость аудитории <strong>${escapeHtml(first.classroomName)}</strong> составляет <strong>${capacity} чел.</strong>, однако на занятие назначено <strong>${totalStudents} человек</strong> (группы: ${escapeHtml(groupNamesList)}) на <strong>${first.date} (${first.dayName}), пара №${first.timeSlotOrder}</strong>.`,
                        severity: 'warning'
                    });
                }
            });

            renderConflicts(conflicts, scheduleLoad, { startDate, endDate });
        } catch (e) {
            console.error('Не удалось выполнить проверку конфликтов', {
                errorType: e?.name || 'Error'
            });
            conflictsContainer.innerHTML = renderCheckStateCard({
                tone: 'error',
                title: 'Проверка не выполнена',
                description: 'Во время анализа произошла ошибка. Повторите проверку позже.'
            });
        } finally {
            conflictsContainer.removeAttribute('aria-busy');
        }
    }

    function renderConflicts(conflicts, scheduleLoad, range) {
        const stateCards = [];
        const presentation = conflictCheckPresentation(scheduleLoad, conflicts.length, range);

        if (scheduleLoad.state === CONFLICT_CHECK_STATE.NOT_RUN) {
            conflictsContainer.innerHTML = renderCheckStateCard(presentation);
            return;
        }

        if (presentation) {
            stateCards.push(renderCheckStateCard(presentation));
        }

        if (!conflicts.length) {
            conflictsContainer.innerHTML = stateCards.join('');
            return;
        }

        const conflictCards = conflicts.map(c => {
            const isError = c.severity === 'error';
            const badgeIcon = isError 
                ? `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>`
                : `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>`;

            return `
                <div class="dashboard-conflict-card dashboard-conflict-card--${isError ? 'error' : 'warning'}">
                    <div class="dashboard-conflict-card__icon">${badgeIcon}</div>
                    <div class="dashboard-conflict-card__body">
                        <h4>${escapeHtml(c.title)}</h4>
                        <p>${escapeHtml(c.description)}</p>
                    </div>
                </div>
            `;
        }).join('');
        conflictsContainer.innerHTML = stateCards.join('') + conflictCards;
    }

    function renderCheckStateCard({ tone, title, description, meta = '' }) {
        const icon = tone === 'success'
            ? '<path d="M20 6 9 17l-5-5" />'
            : tone === 'warning'
                ? '<path d="M12 9v4m0 4h.01" /><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" />'
                : '<circle cx="12" cy="12" r="9" /><path d="M12 8v5m0 3h.01" />';
        return `
            <section class="dashboard-check-state dashboard-check-state--${tone}">
                <span class="dashboard-check-state__icon" aria-hidden="true">
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">${icon}</svg>
                </span>
                <span class="dashboard-check-state__body">
                    <strong>${escapeHtml(title)}</strong>
                    <span>${escapeHtml(description)}</span>
                    ${meta ? `<small>${escapeHtml(meta)}</small>` : ''}
                </span>
            </section>
        `;
    }

    // Загружаем данные при старте
    await loadData();

    // Запускаем периодическое обновление (каждые 30 секунд для пар в реальном времени)
    const realtimeTimer = setInterval(() => {
        if (document.getElementById('current-time-slot')) {
            updateRealtimeMonitoring();
        } else {
            clearInterval(realtimeTimer);
        }
    }, 30000);
}
