(() => {
  const button = document.querySelector('[data-blog-calendar-toggle]');
  const panel = document.querySelector('[data-blog-calendar-panel]');
  const closeButton = document.querySelector('[data-blog-calendar-close]');
  const calendarRoot = document.querySelector('[data-blog-calendar-root]');
  const status = document.querySelector('[data-blog-calendar-status]');

  if (!button || !panel || !calendarRoot || !status) {
    return;
  }

  const languagePrefix = document.documentElement.getAttribute('data-language-prefix') || '';

  const labels = {
    loading: panel.getAttribute('data-i18n-loading') || 'Loading calendar…',
    error: panel.getAttribute('data-i18n-error') || 'Calendar data could not be loaded.',
  };

  let isInitialized = false;
  let years = {};
  let months = {};
  let days = {};
  let maxYearCount = 0;
  let maxMonthCount = 0;
  let maxDayCount = 0;

  function pad2(value) {
    return String(value).padStart(2, '0');
  }

  function normalizeCountMap(value) {
    if (!value || typeof value !== 'object') {
      return {};
    }

    const map = {};
    for (const [key, rawCount] of Object.entries(value)) {
      const count = Number(rawCount);
      if (!Number.isFinite(count) || count <= 0) {
        continue;
      }
      map[key] = Math.floor(count);
    }

    return map;
  }

  function computeMaxCount(value) {
    const counts = Object.values(value || {});
    if (counts.length === 0) {
      return 0;
    }
    return Math.max(...counts.map((count) => Number(count) || 0));
  }

  function applyHeatStyle(target, count, maxCount) {
    if (!(target instanceof HTMLElement) || !Number.isFinite(count) || count <= 0 || !Number.isFinite(maxCount) || maxCount <= 0) {
      target?.style?.setProperty('--blog-calendar-heat-strength', '0%');
      return;
    }

    const normalized = Math.min(1, count / maxCount);
    const strength = Math.round(30 + normalized * 60);

    target.style.setProperty('--blog-calendar-heat-strength', String(strength) + '%');
  }

  function navigateTo(pathname) {
    if (!pathname) {
      return;
    }
    window.location.assign(languagePrefix + pathname);
  }

  function parseInitialYearMonth() {
    const initialYearRaw = button.getAttribute('data-blog-calendar-year');
    const initialMonthRaw = button.getAttribute('data-blog-calendar-month');

    const initialYear = Number(initialYearRaw);
    const initialMonth = Number(initialMonthRaw);

    let selectedYear = Number.isInteger(initialYear) && initialYear > 0 ? initialYear : null;
    let selectedMonth = Number.isInteger(initialMonth) && initialMonth >= 1 && initialMonth <= 12
      ? (initialMonth - 1)
      : null;

    if (!Number.isInteger(selectedYear) || !Number.isInteger(selectedMonth)) {
      const rawPathname = window.location.pathname || '';
      const pathname = languagePrefix && rawPathname.startsWith(languagePrefix + '/')
        ? rawPathname.slice(languagePrefix.length)
        : rawPathname;
      const parts = pathname.split('/').filter(Boolean);
      const pathYear = Number(parts[0]);
      const pathMonth = Number(parts[1]);

      if (!Number.isInteger(selectedYear) && Number.isInteger(pathYear) && pathYear > 0 && String(parts[0]).length === 4) {
        selectedYear = pathYear;
      }

      if (!Number.isInteger(selectedMonth) && Number.isInteger(pathMonth) && pathMonth >= 1 && pathMonth <= 12) {
        selectedMonth = pathMonth - 1;
      }
    }

    return { selectedYear, selectedMonth };
  }

  async function loadCalendarData() {
    const response = await fetch('/calendar.json', { cache: 'no-store' });
    if (!response.ok) {
      throw new Error('calendar.json request failed');
    }

    const parsed = await response.json();
    years = normalizeCountMap(parsed?.years);
    months = normalizeCountMap(parsed?.months);
    days = normalizeCountMap(parsed?.days);
    maxYearCount = computeMaxCount(years);
    maxMonthCount = computeMaxCount(months);
    maxDayCount = computeMaxCount(days);
  }

  function getDateFromClickEvent(event) {
    if (!(event?.target instanceof Element)) {
      return '';
    }

    const dateEl = event.target.closest('[data-vc-date]');
    if (!(dateEl instanceof HTMLElement)) {
      return '';
    }

    return dateEl.dataset.vcDate || '';
  }

  async function initializeCalendar() {
    if (isInitialized) {
      return;
    }

    status.textContent = labels.loading;

    try {
      await loadCalendarData();

      const Calendar = window.VanillaCalendarPro?.Calendar;
      if (typeof Calendar !== 'function') {
        throw new Error('Vanilla Calendar Pro is unavailable');
      }

      const initialYearMonth = parseInitialYearMonth();
      const calendarOptions = {
        ...(Number.isInteger(initialYearMonth.selectedYear) ? { selectedYear: initialYearMonth.selectedYear } : {}),
        ...(Number.isInteger(initialYearMonth.selectedMonth) ? { selectedMonth: initialYearMonth.selectedMonth } : {}),
        onCreateDateEls(_self, dateEl) {
          const dateKey = dateEl.dataset.vcDate || '';
          const count = Number(days[dateKey] || 0);
          const buttonEl = dateEl.querySelector('[data-vc-date-btn]');

          if (!(buttonEl instanceof HTMLElement)) {
            return;
          }

          if (count <= 0) {
            dateEl.removeAttribute('data-blog-calendar-has-posts');
            applyHeatStyle(buttonEl, 0, maxDayCount);
            return;
          }

          dateEl.setAttribute('data-blog-calendar-has-posts', 'true');
          applyHeatStyle(buttonEl, count, maxDayCount);
        },
        onCreateMonthEls(self, monthEl) {
          if (!(monthEl instanceof HTMLElement)) {
            return;
          }

          const monthIndex = Number(monthEl.dataset.vcMonthsMonth);
          const selectedYear = Number(self?.context?.selectedYear);
          if (!Number.isInteger(monthIndex) || !Number.isInteger(selectedYear)) {
            monthEl.removeAttribute('data-blog-calendar-has-posts');
            applyHeatStyle(monthEl, 0, maxMonthCount);
            return;
          }

          const monthKey = String(selectedYear) + '-' + pad2(monthIndex + 1);
          const count = Number(months[monthKey] || 0);
          if (count <= 0) {
            monthEl.removeAttribute('data-blog-calendar-has-posts');
            applyHeatStyle(monthEl, 0, maxMonthCount);
            return;
          }

          monthEl.setAttribute('data-blog-calendar-has-posts', 'true');
          applyHeatStyle(monthEl, count, maxMonthCount);
        },
        onCreateYearEls(_self, yearEl) {
          if (!(yearEl instanceof HTMLElement)) {
            return;
          }

          const yearValue = Number(yearEl.dataset.vcYearsYear);
          if (!Number.isInteger(yearValue)) {
            yearEl.removeAttribute('data-blog-calendar-has-posts');
            applyHeatStyle(yearEl, 0, maxYearCount);
            return;
          }

          const yearKey = String(yearValue);
          const count = Number(years[yearKey] || 0);
          if (count <= 0) {
            yearEl.removeAttribute('data-blog-calendar-has-posts');
            applyHeatStyle(yearEl, 0, maxYearCount);
            return;
          }

          yearEl.setAttribute('data-blog-calendar-has-posts', 'true');
          applyHeatStyle(yearEl, count, maxYearCount);
        },
        onClickDate(_self, event) {
          const dateKey = getDateFromClickEvent(event);
          if (!dateKey || !days[dateKey]) {
            return;
          }

          const [year, month, day] = dateKey.split('-');
          if (!year || !month || !day) {
            return;
          }

          navigateTo('/' + year + '/' + month + '/' + day + '/');
        },
        onClickMonth(self) {
          const selectedYear = Number(self?.context?.selectedYear);
          const selectedMonth = Number(self?.context?.selectedMonth);

          if (!Number.isInteger(selectedYear) || !Number.isInteger(selectedMonth)) {
            return;
          }

          const monthKey = String(selectedYear) + '-' + pad2(selectedMonth + 1);
          if (!months[monthKey]) {
            return;
          }

          navigateTo('/' + String(selectedYear) + '/' + pad2(selectedMonth + 1) + '/');
        },
        onClickYear(self) {
          const selectedYear = Number(self?.context?.selectedYear);

          if (!Number.isInteger(selectedYear)) {
            return;
          }

          const yearKey = String(selectedYear);
          if (!years[yearKey]) {
            return;
          }

          navigateTo('/' + String(selectedYear) + '/');
        },
      };

      const calendar = new Calendar('[data-blog-calendar-root]', calendarOptions);

      calendar.init();
      status.textContent = '';
      status.setAttribute('hidden', 'hidden');
      isInitialized = true;
    } catch {
      status.textContent = labels.error;
      status.removeAttribute('hidden');
    }
  }

  function setPanelOpen(isOpen) {
    if (isOpen) {
      panel.removeAttribute('hidden');
      void initializeCalendar();
      return;
    }

    panel.setAttribute('hidden', 'hidden');
  }

  button.addEventListener('click', () => {
    const isHidden = panel.hasAttribute('hidden');
    setPanelOpen(isHidden);
  });

  if (closeButton) {
    closeButton.addEventListener('click', () => {
      setPanelOpen(false);
    });
  }
})();
