/**
 * Прогресс курса → .kb-course-card--progress
 *
 * Считаем только:
 *   - user-state-need_accomplish  → осталось
 *   - user-state-accomplished / user-state-passed / user-state-processed → выполнено
 * Не считаем:
 *   - user-state-reached, user-state-has_mission, user-state-answered,
 *     user-state-not_reached, first-unreached
 *
 * Имя: AJAX /pl/{window.accountUserId} → h2.xdget-profileTitle → .kb-course-card__name
 */
$(function () {
    var PROFILE_NAME_CACHE_KEY = 'kbclinic_profile_display_name';
    var profileNameFetchStarted = false;

    function pluralTasks(n) {
        var n10 = n % 10;
        var n100 = n % 100;
        if (n10 === 1 && n100 !== 11) return 'задание';
        if (n10 >= 2 && n10 <= 4 && (n100 < 12 || n100 > 14)) return 'задания';
        return 'заданий';
    }

    function setCardUserName(name) {
        var text = String(name || '').replace(/\s+/g, ' ').trim();
        if (!text) return;
        document.querySelectorAll('.kb-course-card__name').forEach(function (el) {
            el.textContent = text;
        });
    }

    function parseProfileTitleFromHtml(html) {
        var $dom = $('<div></div>').append($.parseHTML(html, document, false));
        var title = $dom.find('h2.xdget-profileTitle, .xdget-profileTitle').first().text();
        return String(title || '').replace(/\s+/g, ' ').trim();
    }

    function fillUserNameFromProfile() {
        var nameEl = document.querySelector('.kb-course-card__name');
        if (!nameEl) return;

        var userId = window.accountUserId;
        if (!userId) return;

        var cacheKey = PROFILE_NAME_CACHE_KEY + ':' + userId;
        try {
            var cached = sessionStorage.getItem(cacheKey);
            if (cached) {
                setCardUserName(cached);
                return;
            }
        } catch (e) {
            /* private mode / blocked */
        }

        if (profileNameFetchStarted) return;
        profileNameFetchStarted = true;

        $.ajax({
            method: 'GET',
            url: '/pl/' + encodeURIComponent(userId),
            dataType: 'html',
        })
            .done(function (html) {
                var name = parseProfileTitleFromHtml(html);
                if (!name) return;
                try {
                    sessionStorage.setItem(cacheKey, name);
                } catch (e) {
                    /* ignore */
                }
                setCardUserName(name);
            })
            .fail(function () {
                profileNameFetchStarted = false;
            });
    }

    function isLessonDone(el) {
        return (
            el.classList.contains('user-state-accomplished') ||
            el.classList.contains('user-state-passed') ||
            el.classList.contains('user-state-processed')
        );
    }

    function isLessonCounted(el) {
        if (isLessonDone(el)) return true;
        return el.classList.contains('user-state-need_accomplish');
    }

    function updateKbProgressCard(done, total) {
        var card = document.querySelector('.kb-course-card--progress');
        if (!card) return;

        done = Math.max(0, Number(done) || 0);
        total = Math.max(0, Number(total) || 0);
        var left = Math.max(0, total - done);
        var percent = total > 0 ? Math.round((done * 100) / total) : 0;

        var ring = card.querySelector('.kb-course-card__ring');
        var value = card.querySelector('.kb-course-card__ring-value');
        var doneEl = card.querySelector('.kb-course-card__stat--done');
        var leftEl = card.querySelector('.kb-course-card__stat--left');

        if (ring) ring.style.setProperty('--kb-progress', String(percent));
        if (value) value.textContent = percent + '%';
        if (doneEl) {
            doneEl.textContent = 'Выполнено: ' + done + ' ' + pluralTasks(done);
        }
        if (leftEl) {
            leftEl.textContent = 'Осталось: ' + left + ' ' + pluralTasks(left);
        }

        card.setAttribute('data-kb-progress', String(percent));
        card.setAttribute('data-kb-done', String(done));
        card.setAttribute('data-kb-total', String(total));
    }

    function countLessonsFromRoot(root) {
        var $root = root && root.jquery ? root : $(root || document);
        var $list = $root.find('.lesson-list > li').not('.lesson-is-hidden');
        var done = 0;
        var total = 0;

        $list.each(function () {
            if (!isLessonCounted(this)) return;
            total += 1;
            if (isLessonDone(this)) done += 1;
        });

        return { done: done, total: total };
    }

    function countLessonsFromHtml(html) {
        var $dom = $('<div></div>').append($.parseHTML(html, document, false));
        return countLessonsFromRoot($dom);
    }

    function extractStreamId(href) {
        if (!href) return null;
        var m = String(href).match(/\/stream\/view\/id\/(\d+)/);
        if (m) return m[1];
        m = String(href).match(/[?&]id=(\d+)/);
        return m ? m[1] : null;
    }

    function getModuleIdsToFetch() {
        var ids = [];
        var seen = {};

        function pushId(id) {
            if (!id || seen[id]) return;
            seen[id] = true;
            ids.push(id);
        }

        document
            .querySelectorAll(
                '.stream-table a[href*="/stream/view"], a.module-card[href], .kb-module-card a[href]'
            )
            .forEach(function (a) {
                pushId(extractStreamId(a.getAttribute('href') || a.href));
            });

        document.querySelectorAll('[data-training-id]').forEach(function (el) {
            pushId(el.getAttribute('data-training-id'));
        });

        return ids;
    }

    function fetchAndAggregate(ids) {
        if (!ids.length) {
            return $.Deferred().resolve({ done: 0, total: 0 }).promise();
        }

        var done = 0;
        var total = 0;

        var reqs = ids.map(function (id) {
            return $.ajax({
                method: 'GET',
                url: '/teach/control/stream/view/id/' + id,
                dataType: 'html',
            })
                .done(function (html) {
                    var c = countLessonsFromHtml(html);
                    done += c.done;
                    total += c.total;
                })
                .fail(function () {
                    /* нет доступа / ошибка */
                });
        });

        return $.when.apply($, reqs).then(function () {
            return { done: done, total: total };
        });
    }

    var running = false;
    var ajaxDone = false;

    function runProgress() {
        var card = document.querySelector('.kb-course-card--progress');
        if (!card) return;

        fillUserNameFromProfile();

        // 1) Есть lesson-list на странице — считаем локально
        var local = countLessonsFromRoot(document);
        if (local.total > 0) {
            updateKbProgressCard(local.done, local.total);
            return;
        }

        // 2) Страница модулей — AJAX по каждому модулю (один раз)
        if (ajaxDone || running) return;

        var ids = getModuleIdsToFetch();
        if (!ids.length) return;

        running = true;
        card.classList.add('kb-course-card--progress-loading');

        fetchAndAggregate(ids)
            .done(function (r) {
                ajaxDone = true;
                updateKbProgressCard(r.done, r.total);
            })
            .always(function () {
                running = false;
                card.classList.remove('kb-course-card--progress-loading');
            });
    }

    runProgress();
    setTimeout(runProgress, 300);
    setTimeout(runProgress, 800);
    setTimeout(runProgress, 1600);

    if (typeof MutationObserver !== 'undefined') {
        var timer = null;
        var obs = new MutationObserver(function () {
            if (!document.querySelector('.kb-course-card--progress')) return;
            clearTimeout(timer);
            timer = setTimeout(runProgress, 200);
        });
        obs.observe(document.body, { childList: true, subtree: true });
    }
});
