/* GETCOURSE — CURATOR / TRAININGS LIST v0.3.1 */
(() => {
  'use strict';

  const ROUTE_RE = /^\/teach\/control(?:\/stream(?:\/index)?)?\/?$/;
  const REQUEST_TIMEOUT = 12000;
  const fetchCache = new Map();

  const isCurator = () => {
    const u = window.userInfo || {};
    return !!u.isTeacher && !u.isAdmin && !u.isManager;
  };

  if (!ROUTE_RE.test(location.pathname) || !isCurator()) return;

  document.documentElement.classList.add('psych-curator-courses-loading');

  const cleanText = value => String(value || '').replace(/\s+/g, ' ').trim();

  const iconBook = () => `
    <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path d="M5.5 4.75A2.75 2.75 0 0 1 8.25 2h10.25v16.25H8.25A2.75 2.75 0 0 0 5.5 21V4.75Z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>
      <path d="M5.5 18.25A2.75 2.75 0 0 1 8.25 15.5H18.5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
    </svg>`;

  const iconForward = () => `
    <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path d="M5 12h14M14 7l5 5-5 5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>`;

  const iconAttention = () => `
    <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <circle cx="12" cy="12" r="8" stroke="currentColor" stroke-width="1.7"/>
      <path d="M12 7.5v5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
      <circle cx="12" cy="16.2" r="1" fill="currentColor"/>
    </svg>`;

  function getCourses() {
    return [...document.querySelectorAll('.xdget-trainingList .stream-table .training-row')]
      .map(row => {
        const link = row.querySelector('td > a[href]');
        const titleNode = row.querySelector('.stream-title');
        if (!link || !titleNode) return null;

        const href = link.getAttribute('href') || '#';
        const id = String(
          row.getAttribute('data-training-id') ||
          href.match(/\/id\/(\d+)/)?.[1] ||
          href
        );

        const meta = cleanText(link.querySelector('div')?.textContent);
        /*
         * GetCourse gives meta like:
         *   "33 урока. 15 поток"
         *   "40 уроков."
         *
         * Remove the WHOLE Russian word form, not only the stem "урок".
         * Otherwise leftovers like "а." / "ов." appear in the UI.
         */
        const lessonsMatch = meta.match(/(\d+)\s+урок(?:ов|а)?\.?/i);
        const lessons = lessonsMatch ? Number(lessonsMatch[1]) : null;

        let extra = meta;
        if (lessonsMatch) {
          extra = cleanText(meta.replace(lessonsMatch[0], ''))
            .replace(/^[.,;:·\-–—\s]+|[.,;:·\-–—\s]+$/g, '');
        }

        return {
          id,
          href,
          title: cleanText(titleNode.textContent),
          lessons,
          extra
        };
      })
      .filter(Boolean);
  }

  async function fetchText(url) {
    const absolute = new URL(url, location.origin).href;
    if (fetchCache.has(absolute)) return fetchCache.get(absolute);

    const promise = (async () => {
      const controller = new AbortController();
      const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
      try {
        /*
         * Важно: не добавляем X-Requested-With.
         * Лента ответов GetCourse при AJAX-запросе может вернуть
         * урезанный/другой вариант страницы без боковых счётчиков
         * .stream-count-{trainingId}. Обычный navigation-like fetch
         * возвращает тот же HTML, который видит пользователь.
         */
        const response = await fetch(absolute, {
          credentials: 'same-origin',
          signal: controller.signal
        });
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return await response.text();
      } finally {
        clearTimeout(timer);
      }
    })();

    fetchCache.set(absolute, promise);
    try {
      return await promise;
    } catch (e) {
      fetchCache.delete(absolute);
      throw e;
    }
  }

  async function fetchDocument(url) {
    const html = await fetchText(url);
    return new DOMParser().parseFromString(html, 'text/html');
  }

  async function loadModuleCount(course) {
    try {
      const doc = await fetchDocument(course.href);
      return doc.querySelectorAll('.xdget-trainingList .stream-table .training-row').length;
    } catch (_) {
      return null;
    }
  }

  function buildTrainingFeedUrl(trainingId, status = '') {
    /*
     * GetCourse стабильно применяет фильтры ленты ответов,
     * когда они переданы в его штатном path-формате.
     * Query string на этой странице может возвращать общую ленту,
     * из-за чего на карточках получался ложный 0.
     */
    const parts = [
      ['filter[only_my_trainings]', '1'],
      ['filter[status]', status],
      ['filter[lesson_type]', ''],
      ['filter[marked]', ''],
      ['filter[sorting]', 'need_teacher_reaction_at DESC'],
      ['filter[answer_type]', 'mission_answer'],
      ['filter[learner_type]', 'only_my'],
      ['filter[training_with_disable_view]', '']
    ];

    const path = parts.map(([key, value]) =>
      `/${encodeURIComponent(key)}/${encodeURIComponent(value)}`
    ).join('');

    return `/teach/control/answers/unanswered${path}/training_id/${encodeURIComponent(trainingId)}`;
  }

  function parseTrainingCount(doc, trainingId) {
    const direct = doc.querySelector(
      `.stream-count-${CSS.escape(String(trainingId))}`
    );

    if (direct) {
      const value = Number(
        cleanText(direct.textContent).replace(/\D+/g, '')
      );

      if (Number.isFinite(value)) return value;
    }

    /*
     * Если в текущей выборке у тренинга нет ответов,
     * GetCourse вообще не выводит его в боковом списке.
     */
    return 0;
  }

  async function loadCourseAnswerCounts(course) {
    const [allResult, pendingResult] = await Promise.allSettled([
      fetchDocument(buildTrainingFeedUrl(course.id, '')),
      fetchDocument(buildTrainingFeedUrl(course.id, 'unanswered'))
    ]);

    return {
      all:
        allResult.status === 'fulfilled'
          ? parseTrainingCount(allResult.value, course.id)
          : 0,
      pending:
        pendingResult.status === 'fulfilled'
          ? parseTrainingCount(pendingResult.value, course.id)
          : 0
    };
  }

  async function loadAnswerCounts(courses) {
    const results = await Promise.allSettled(
      courses.map(loadCourseAnswerCounts)
    );

    const all = new Map();
    const pending = new Map();

    courses.forEach((course, index) => {
      const result = results[index];

      if (result?.status === 'fulfilled') {
        all.set(String(course.id), result.value.all);
        pending.set(String(course.id), result.value.pending);
      } else {
        all.set(String(course.id), 0);
        pending.set(String(course.id), 0);
      }
    });

    return { all, pending };
  }

  function pluralAnswers(n) {
    const a = n % 10, b = n % 100;
    if (a === 1 && b !== 11) return `${n} ответ`;
    if (a >= 2 && a <= 4 && !(b >= 12 && b <= 14)) return `${n} ответа`;
    return `${n} ответов`;
  }

  function pluralModules(n) {
    const a = n % 10, b = n % 100;
    if (a === 1 && b !== 11) return `${n} модуль`;
    if (a >= 2 && a <= 4 && !(b >= 12 && b <= 14)) return `${n} модуля`;
    return `${n} модулей`;
  }

  function courseMeta(course) {
    const parts = [];
    if (Number.isFinite(course.lessons)) parts.push(`${course.lessons} урока`);
    if (Number.isFinite(course.modules) && course.modules > 0) parts.push(pluralModules(course.modules));
    if (course.extra) parts.push(course.extra);
    return parts.join(' · ') || 'Тренинг';
  }

  function makeStatus(course) {
    if (course.pending > 0) return { text: `${course.pending} на проверке`, cls: 'is-pending' };
    if (course.answers > 0) return { text: 'Есть ответы', cls: 'is-active' };
    return { text: 'Нет ответов', cls: 'is-neutral' };
  }

  function buildCard(course) {
    const status = makeStatus(course);
    const card = document.createElement('a');
    card.className = 'psych-curator-course-card';
    card.href = course.href;

    const attention = course.pending > 0 ? `
      <div class="psych-curator-course-card__notice">
        ${iconAttention()}
        <span>${pluralAnswers(course.pending)} требуют проверки</span>
      </div>` : '';

    card.innerHTML = `
      <div class="psych-curator-course-card__top">
        <span class="psych-curator-course-card__icon">${iconBook()}</span>
        <span class="psych-curator-course-card__status ${status.cls}">${status.text}</span>
      </div>
      <div class="psych-curator-course-card__body">
        <h3 class="psych-curator-course-card__title"></h3>
        <p class="psych-curator-course-card__meta"></p>
        <div class="psych-curator-course-card__stats">
          <span>Мои ученики</span>
          <strong>${pluralAnswers(course.answers)}</strong>
        </div>
        ${attention}
      </div>
      <div class="psych-curator-course-card__footer">
        <span>Открыть тренинг</span>${iconForward()}
      </div>`;

    card.querySelector('.psych-curator-course-card__title').textContent = course.title;
    card.querySelector('.psych-curator-course-card__meta').textContent = courseMeta(course);
    return card;
  }

  function pickFocus(courses) {
    return courses.find(c => c.pending > 0) || courses.find(c => c.answers > 0) || courses[0] || null;
  }

  function buildFocus(course) {
    if (!course) return null;
    const wrap = document.createElement('div');
    wrap.className = 'psych-curator-courses-focus';

    const label = course.pending > 0 ? 'Требуют внимания' : 'Продолжить работу';
    const meta = course.pending > 0
      ? `${pluralAnswers(course.answers)} моих учеников · ${pluralAnswers(course.pending)} требуют проверки`
      : `${courseMeta(course)} · ${pluralAnswers(course.answers)} моих учеников`;

    wrap.innerHTML = `
      <a class="psych-curator-courses-focus__card" href="${course.href}">
        <span class="psych-curator-courses-focus__icon">${iconBook()}</span>
        <span class="psych-curator-courses-focus__content">
          <span class="psych-curator-courses-focus__label">${label}</span>
          <span class="psych-curator-courses-focus__title"></span>
          <span class="psych-curator-courses-focus__meta"></span>
        </span>
        <span class="psych-curator-courses-focus__action">Открыть ${iconForward()}</span>
      </a>`;

    wrap.querySelector('.psych-curator-courses-focus__title').textContent = course.title;
    wrap.querySelector('.psych-curator-courses-focus__meta').textContent = meta;
    return wrap;
  }


/* =========================================================
   SCHEDULE + CHATS / shared dashboard block
   ========================================================= */
function psychBuildLearningActivity(options = {}) {
    const nativeRoot = document.querySelector('.xdget-lessonSchedule');
    if (!nativeRoot) return null;

    const schedule = nativeRoot.querySelector('.schedule-block');
    const chats = nativeRoot.querySelector('.chat-list');

    const hasEvents = !!schedule?.querySelector('.day .record');
    const hasChats = !!chats?.querySelector('.chat-item');

    if (!hasEvents && !hasChats) return null;

    const hub = document.createElement('section');
    hub.className = 'psych-learning-activity';
    if (hasEvents && hasChats) hub.classList.add('has-both');
    if (hasEvents && !hasChats) hub.classList.add('has-events-only');
    if (!hasEvents && hasChats) hub.classList.add('has-chats-only');

    if (hasEvents) {
        const eventsSection = document.createElement('div');
        eventsSection.className = 'psych-learning-activity__panel psych-learning-activity__events';

        const head = document.createElement('div');
        head.className = 'psych-learning-activity__head';
        head.innerHTML = `
            <div>
                <h2 class="psych-learning-activity__title">Ближайшие события</h2>
                <p class="psych-learning-activity__subtitle">Расписание занятий и встреч</p>
            </div>
            <a class="psych-learning-activity__all" href="/pl/teach/control/schedule">Все события</a>
        `;

        eventsSection.append(head);
        schedule.classList.add('psych-learning-activity__native-schedule');
        eventsSection.append(schedule);
        hub.append(eventsSection);
    }

    if (hasChats) {
        const chatsSection = document.createElement('div');
        chatsSection.className = 'psych-learning-activity__panel psych-learning-activity__chats';

        const head = document.createElement('div');
        head.className = 'psych-learning-activity__head';
        head.innerHTML = `
            <div>
                <h2 class="psych-learning-activity__title">Чаты</h2>
                <p class="psych-learning-activity__subtitle">Быстрый доступ к обсуждениям</p>
            </div>
            <a class="psych-learning-activity__all" href="/c/my">Все чаты</a>
        `;

        chatsSection.append(head);
        chats.classList.add('psych-learning-activity__native-chats');
        chatsSection.append(chats);
        hub.append(chatsSection);
    }

    if (options.disableFutureEvents === true && hasEvents) {
        psychDisableFutureEvents(hub);
    }

    return hub;
}

function psychDisableFutureEvents(scope) {
    const now = window.nowTime instanceof Date
        ? new Date(window.nowTime.getTime())
        : new Date();

    const months = {
        'янв': 0, 'января': 0,
        'фев': 1, 'февраля': 1,
        'мар': 2, 'марта': 2,
        'апр': 3, 'апреля': 3,
        'май': 4, 'мая': 4,
        'июн': 5, 'июня': 5,
        'июл': 6, 'июля': 6,
        'авг': 7, 'августа': 7,
        'сен': 8, 'сент': 8, 'сентября': 8,
        'окт': 9, 'октября': 9,
        'ноя': 10, 'ноября': 10,
        'дек': 11, 'декабря': 11
    };

    function parseDay(label) {
        const value = String(label || '').trim().toLowerCase();

        if (/^сегодня/.test(value)) {
            return new Date(now.getFullYear(), now.getMonth(), now.getDate());
        }
        if (/^завтра/.test(value)) {
            return new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
        }
        if (/^вчера/.test(value)) {
            return new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
        }

        const match = value.match(/(\d{1,2})\s+([а-яё]+)/i);
        if (!match) return null;

        const day = Number(match[1]);
        const token = match[2].toLowerCase();
        const monthKey = Object.keys(months).find(key => token.startsWith(key));
        if (!monthKey) return null;

        let candidate = new Date(now.getFullYear(), months[monthKey], day);

        const halfYear = 183 * 24 * 60 * 60 * 1000;
        if (candidate.getTime() < now.getTime() - halfYear) {
            candidate = new Date(now.getFullYear() + 1, months[monthKey], day);
        } else if (candidate.getTime() > now.getTime() + halfYear) {
            candidate = new Date(now.getFullYear() - 1, months[monthKey], day);
        }

        return candidate;
    }

    scope.querySelectorAll('.schedule-block .day').forEach(dayNode => {
        const baseDate = parseDay(
            dayNode.querySelector('.day-label')?.textContent
        );
        if (!baseDate) return;

        dayNode.querySelectorAll('.record').forEach(record => {
            const timeText = String(
                record.querySelector('.time')?.textContent || ''
            ).trim();

            const timeMatch = timeText.match(/(\d{1,2}):(\d{2})/);
            const eventDate = new Date(baseDate.getTime());

            if (timeMatch) {
                eventDate.setHours(
                    Number(timeMatch[1]),
                    Number(timeMatch[2]),
                    0,
                    0
                );
            }

            if (eventDate.getTime() <= now.getTime()) return;

            record.classList.add('psych-learning-event--future');

            const event = record.querySelector('.event');
            if (event && !event.querySelector('.psych-learning-event__status')) {
                const status = document.createElement('span');
                status.className = 'psych-learning-event__status';
                status.textContent = 'Скоро';
                event.append(status);
            }

            const link = record.querySelector('.event a[href]');
            if (!link) return;

            link.setAttribute('aria-disabled', 'true');
            link.setAttribute('tabindex', '-1');

            link.addEventListener('click', event => {
                event.preventDefault();
                event.stopPropagation();
                event.stopImmediatePropagation();
            }, true);
        });
    });
}


  function buildDashboard(courses) {
    const root = document.createElement('section');
    root.className = 'psych-curator-courses-dashboard';
    root.innerHTML = `
      <div class="psych-curator-courses-hero">
        <div class="psych-curator-courses-hero__content">
          <h1 class="psych-curator-courses-hero__title">Кабинет куратора</h1>
          <p class="psych-curator-courses-hero__subtitle">Тренинги, в которых вы назначены преподавателем</p>
        </div>
      </div>`;

    const focus = buildFocus(pickFocus(courses));
    if (focus) root.append(focus);

    const activityHub = psychBuildLearningActivity({
      disableFutureEvents: false
    });
    if (activityHub) root.append(activityHub);

    const section = document.createElement('div');
    section.innerHTML = `
      <div class="psych-curator-courses-section">
        <h2 class="psych-curator-courses-section__title">Мои тренинги</h2>
        <span class="psych-curator-courses-section__count">${courses.length}</span>
      </div>
      <div class="psych-curator-courses-grid"></div>`;
    root.append(section);

    const grid = root.querySelector('.psych-curator-courses-grid');
    courses.forEach(course => grid.append(buildCard(course)));
    return root;
  }

  function suppressStudentDashboard(root = document) {
    root.querySelectorAll('.psych-user-courses-dashboard').forEach(el => {
      el.style.setProperty('display', 'none', 'important');
    });
  }

  let started = false;

  async function init() {
    if (started || !isCurator()) return;
    const table = document.querySelector('.xdget-trainingList .stream-table');
    const container = document.querySelector('.main-page-block > .container');
    if (!table || !container) return;

    started = true;

    try {
      const courses = getCourses();
      const [counts, modules] = await Promise.all([
        loadAnswerCounts(courses),
        Promise.allSettled(courses.map(loadModuleCount))
      ]);

      courses.forEach((course, i) => {
        course.answers = counts.all.get(String(course.id)) || 0;
        course.pending = counts.pending.get(String(course.id)) || 0;
        course.modules = modules[i]?.status === 'fulfilled' ? modules[i].value : null;
      });

      suppressStudentDashboard();
      document.querySelector('.psych-curator-courses-dashboard')?.remove();
      container.append(buildDashboard(courses));

      document.documentElement.classList.remove('psych-curator-courses-loading');
      document.documentElement.classList.add('psych-curator-courses-ready');
      document.body.classList.add('psych-curator-courses-ready');
    } catch (error) {
      console.warn('[CURATOR COURSES]', error);
      document.documentElement.classList.remove('psych-curator-courses-loading');
      started = false;
    }
  }

  new MutationObserver(() => {
    suppressStudentDashboard();
    if (!started) init();
  }).observe(document.documentElement, { childList: true, subtree: true });

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init, { once: true });
  } else {
    init();
  }

  setTimeout(init, 250);
  setTimeout(init, 700);
  setTimeout(init, 1400);

  setTimeout(() => {
    if (!document.querySelector('.psych-curator-courses-dashboard')) {
      document.documentElement.classList.remove('psych-curator-courses-loading');
    }
  }, 4000);
})();
