const sdk = window.mightyInteractiveSdk;

const defaultState = {
  introContent: '<h1>Section heading goes here</h1><p>Add a short introduction.</p><p><em>Open each section to learn more.</em></p>',
  pageBackground: '',
  regionLabel: 'Accordion content',
  allowMultipleOpen: false,
  items: [
    {
      title: 'Section one',
      color: '#4f8640',
      textColor: '#ffffff',
      openBackground: '',
      image: null,
      imageAlt: '',
      content: '<p>Add your content here.</p>'
    },
    {
      title: 'Section two',
      color: '#e2ab45',
      textColor: '#1f2430',
      openBackground: '',
      image: null,
      imageAlt: '',
      content: '<p>Add your content here.</p>'
    },
    {
      title: 'Section three',
      color: '#b83a2f',
      textColor: '#ffffff',
      openBackground: '',
      image: null,
      imageAlt: '',
      content: '<p>Add your content here.</p>'
    }
  ]
};

const refs = {
  intro: document.getElementById('accordion-intro'),
  accordion: document.getElementById('accordion-list')
};

const visited = new Set();
let config = normalizeState(defaultState);
let keydownBound = false;

sdk.onSdkReady(async () => {
  config = normalizeState(await sdk.state.getState(defaultState, 2000));
  render(config);

  if (sdk.isCompleted && config.items.length > 0) {
    config.items.forEach((item) => visited.add(item.id));
    render(config);
  }
});

function normalizeState(raw) {
  const merged = { ...defaultState, ...(raw || {}) };
  const items = Array.isArray(merged.items) ? merged.items : defaultState.items;

  return {
    introContent: typeof merged.introContent === 'string' && merged.introContent.trim()
      ? merged.introContent
      : defaultState.introContent,
    pageBackground: isHexColor(merged.pageBackground) ? merged.pageBackground : '',
    regionLabel: merged.regionLabel || defaultState.regionLabel,
    allowMultipleOpen: Boolean(merged.allowMultipleOpen),
    items: items.map((item, index) => ({
      id: item.id || `item-${index + 1}`,
      title: item.title || `Section ${index + 1}`,
      color: isHexColor(item.color) ? item.color : defaultState.items[index % defaultState.items.length].color,
      textColor: isHexColor(item.textColor) ? item.textColor : '#ffffff',
      openBackground: isHexColor(item.openBackground) ? item.openBackground : '',
      image: item.image || null,
      imageAlt: item.imageAlt || '',
      content: typeof item.content === 'string' ? item.content : ''
    })).filter((item) => item.title || item.content)
  };
}

function render(state) {
  document.documentElement.style.setProperty('--page-bg', state.pageBackground || 'transparent');
  refs.intro.innerHTML = state.introContent;
  refs.accordion.setAttribute('aria-label', state.regionLabel);

  if (!state.items.length) {
    refs.accordion.innerHTML = '<div class="empty-state">No accordion sections have been configured yet.</div>';
    return;
  }

  refs.accordion.innerHTML = state.items.map((item, index) => {
    const buttonId = `acc-${index + 1}`;
    const panelId = `panel-${index + 1}`;
    const imageUrl = item.image?.url || '';
    const imageAlt = item.imageAlt || item.image?.filename || '';
    const openBackground = item.openBackground || '#ffffff';
    const isVisited = visited.has(item.id);

    return `
      <article class="item" style="--open-content-bg:${escapeAttribute(openBackground)};">
        <div class="item-shell">
          <h2>
            <button
              type="button"
              class="trigger"
              aria-expanded="false"
              aria-controls="${panelId}"
              id="${buttonId}"
              data-item-id="${escapeAttribute(item.id)}"
            >
              <div class="trigger-bar" style="background:${escapeAttribute(item.color)}; color:${escapeAttribute(item.textColor)};">
                <span class="title">${escapeHtml(item.title)}</span>
                <span class="chev" aria-hidden="true">▾</span>
              </div>
            </button>
          </h2>
          <div id="${panelId}" class="panel" role="region" aria-labelledby="${buttonId}" hidden>
            ${imageUrl ? `<img class="hero-image" src="${escapeAttribute(imageUrl)}" alt="${escapeAttribute(imageAlt)}">` : ''}
            <div class="content">${item.content}</div>
          </div>
        </div>
      </article>
    `;
  }).join('');

  const triggers = Array.from(document.querySelectorAll('.trigger'));
  triggers.forEach((btn) => {
    btn.addEventListener('click', () => toggle(btn, state.allowMultipleOpen));
  });

  if (!keydownBound) {
    document.addEventListener('keydown', handleKeyNavigation);
    keydownBound = true;
  }

  updateCompletion();
}

function toggle(btn, allowMultipleOpen) {
  const panel = document.getElementById(btn.getAttribute('aria-controls'));
  const open = btn.getAttribute('aria-expanded') === 'true';
  const itemId = btn.dataset.itemId;

  if (!open && !allowMultipleOpen) {
    document.querySelectorAll('.trigger[aria-expanded="true"]').forEach((openBtn) => {
      if (openBtn !== btn) {
        openBtn.setAttribute('aria-expanded', 'false');
        const openPanel = document.getElementById(openBtn.getAttribute('aria-controls'));
        if (openPanel) openPanel.hidden = true;
      }
    });
  }

  btn.setAttribute('aria-expanded', String(!open));
  panel.hidden = open;

  if (!open && !visited.has(itemId)) {
    visited.add(itemId);
    updateCompletion();
  }
}

function updateCompletion() {
  if (config.items.length > 0 && visited.size >= config.items.length) {
    sdk.markAsComplete();
  }
}

function handleKeyNavigation(event) {
  const triggers = Array.from(document.querySelectorAll('.trigger'));
  const current = document.activeElement;
  if (!current || !current.classList.contains('trigger')) return;

  const currentIndex = triggers.indexOf(current);
  if (currentIndex === -1) return;

  if (event.key === 'ArrowDown') {
    event.preventDefault();
    triggers[(currentIndex + 1) % triggers.length].focus();
  } else if (event.key === 'ArrowUp') {
    event.preventDefault();
    triggers[(currentIndex - 1 + triggers.length) % triggers.length].focus();
  } else if (event.key === 'Home') {
    event.preventDefault();
    triggers[0].focus();
  } else if (event.key === 'End') {
    event.preventDefault();
    triggers[triggers.length - 1].focus();
  } else if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault();
    current.click();
  }
}

function isHexColor(value) {
  return typeof value === 'string' && /^#[0-9a-fA-F]{6}$/.test(value.trim());
}

function escapeHtml(value) {
  return String(value)
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

function escapeAttribute(value) {
  return escapeHtml(value).replaceAll('`', '&#96;');
}
