<script>
  /**
   * Rebuilds the item list for a page from pre-computed htmlGroups when the light report omits page.items.
   */
  function buildItemsFromHtmlGroupsForPage(page, ruleInCategory) {
    const htmlGroups = ruleInCategory.htmlGroups || {};
    const resolvedItems = [];

    Object.values(htmlGroups).forEach(groupData => {
      if (!Array.isArray(groupData.pageUrls) || !groupData.pageUrls.includes(page.url)) {
        return;
      }

      resolvedItems.push({
        html: groupData.html,
        xpath: groupData.xpath,
        message: groupData.message,
        screenshotPath: groupData.screenshotPath,
        displayNeedsReview: groupData.displayNeedsReview,
        pageUrl: page.url,
        pageTitle: page.pageTitle || page.metadata
      });
    });

    return resolvedItems;
  }

  /**
   * The embedded report payload now omits page.items and rebuilds occurrences from
   * htmlGroups + page metadata. Keep the older page.items resolution logic below
   * commented for an easy rollback if we need to restore mixed payload support.
   */
  function resolveItemReferencesForPage(page, ruleInCategory) {
    return buildItemsFromHtmlGroupsForPage(page, ruleInCategory);

    /*
    const items = page.items || [];

    if (items.length === 0) {
      return buildItemsFromHtmlGroupsForPage(page, ruleInCategory);
    }

    const isReference = typeof items[0] === 'string';

    if (!isReference) {
      return items;
    }

    const htmlGroups = ruleInCategory.htmlGroups || {};

    return items.map(compositeKey => {
      const groupData = htmlGroups[compositeKey];
      if (groupData) {
        return {
          html: groupData.html,
          xpath: groupData.xpath,
          message: groupData.message,
          screenshotPath: groupData.screenshotPath,
          displayNeedsReview: groupData.displayNeedsReview,
          pageUrl: page.url,
          pageTitle: page.pageTitle || page.metadata
        };
      }

      // Fallback: parse composite key
      const nullByteIndex = compositeKey.indexOf('\x00');
      const html = nullByteIndex !== -1 ? compositeKey.slice(0, nullByteIndex) : compositeKey;
      const xpath = nullByteIndex !== -1 ? compositeKey.slice(nullByteIndex + 1) : '';
      return {
        html,
        xpath,
        message: '',
        screenshotPath: '',
        pageUrl: page.url,
        pageTitle: page.pageTitle || page.metadata
      };
    });
    */
  }

  function buildItemCardsWithPagination(accordionId, category, ruleInCategory, page, index) {
    const accordionAIId = `${ruleInCategory.rule}-${category}-accordion-AI-${index}`;
    const buttonAIId = `${ruleInCategory.rule}-${category}-button-AI-${index}`;
    const errorAIId = `${ruleInCategory.rule}-${category}-error-AI-${index}`;
    const genAiAccordionId = `${ruleInCategory.rule}-${category}-genai-accordion-${index}`;
    const genAiButtonId = `${ruleInCategory.rule}-${category}-genai-button-${index}`;
    const genAiErrorId = `${ruleInCategory.rule}-${category}-genai-error-${index}`;
    const accordion = document.getElementById(`${accordionId}-title`).parentElement.parentElement
      .parentElement;

    const accordionBody = accordion.getElementsByClassName('accordion-body')[0];

    // Resolve item references if needed
    const resolvedItems = resolveItemReferencesForPage(page, ruleInCategory);
    const totalItems = resolvedItems.length;
    let currentItemIndex = 0;

    // Create pagination controls
    const paginationControls = createPaginationControls(totalItems);

    // Create container for the single item card
    const itemCardContainer = createElementFromString('<div></div>');

    // Function to render a specific item
    async function renderItem(itemIndex) {
      const item = resolvedItems[itemIndex];
      const accordionDivToAppendAI = `${accordionAIId}-${itemIndex}`;
      const buttonDivForAiFeedback = `${buttonAIId}-${itemIndex}`;
      const aiErrorDiv = `${errorAIId}-${itemIndex}`;
      const genAiAccordionDiv = `${genAiAccordionId}-${itemIndex}`;
      const genAiButtonDiv = `${genAiButtonId}-${itemIndex}`;
      const genAiErrorDiv = `${genAiErrorId}-${itemIndex}`;

      const isPurpleAiRule = oobeeAiRules.includes(ruleInCategory.rule);
      let oobeeAiQueryLabel;
      if (isPurpleAiRule) {
        oobeeAiQueryLabel = await checkPurpleAiQueryLabel(ruleInCategory.rule, item.html);
      }

      const itemCard = createItemCard(item, isPurpleAiRule, oobeeAiQueryLabel, {
        accordionDivToAppendAI,
        buttonDivForAiFeedback,
        aiErrorDiv,
        genAiAccordionDiv,
        genAiButtonDiv,
        genAiErrorDiv,
        ruleInCategory,
      });

      // Clear and update the container
      itemCardContainer.replaceChildren(itemCard);

      // Setup copy button functionality
      setupCopyButton(itemCard, item.xpath);

      // Highlight code
      hljs.configure({ ignoreUnescapedHTML: true });
      hljs.highlightAll();
    }

    // Function to update pagination state
    function updatePaginationState() {
      const prevBtn = paginationControls.querySelector('.pagination-prev');
      const nextBtn = paginationControls.querySelector('.pagination-next');
      const pageInput = paginationControls.querySelector('.pagination-page-input');

      prevBtn.disabled = currentItemIndex === 0;
      nextBtn.disabled = currentItemIndex === totalItems - 1;
      pageInput.value = currentItemIndex + 1;
    }

    // Setup pagination event handlers
    setupPaginationHandlers(paginationControls, totalItems, {
      onPageChange: newIndex => {
        currentItemIndex = newIndex;
        renderItem(currentItemIndex);
        updatePaginationState();
      },
    });

    // Append pagination and container to accordion body
    accordionBody.appendChild(paginationControls);
    accordionBody.appendChild(itemCardContainer);

    // Render the first item
    renderItem(0);
  }

  function createPaginationControls(totalItems) {
    return createElementFromString(`
      <div class="item-pagination-controls">
        <div class="mr-1">Occurrence no.</div>
        <button class="pagination-arrow pagination-prev" aria-label="Previous item" disabled>
            <svg width="8" height="12" viewBox="0 0 8 12" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M7.41 1.41L6 0L0 6L6 12L7.41 10.59L2.83 6L7.41 1.41Z" fill="#4D34BF"/>
            </svg>
        </button>
        <div class="pagination-page-info">
          <input type="number" class="pagination-page-input" value="1" min="1" max="${totalItems}" aria-label="Current page number" />
        </div>
        <button class="pagination-arrow pagination-next" aria-label="Next item" ${totalItems <= 1 ? 'disabled' : ''}>
            <svg width="8" height="12" viewBox="0 0 8 12" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M1.41 0L0 1.41L4.58 6L0 10.59L1.41 12L7.41 6L1.41 0Z" fill="#4D34BF"/>
            </svg>
        </button>
        <div class="mr-1">of ${totalItems}</div>
      </div>
    `);
  }

  function setupPaginationHandlers(paginationControls, totalItems, callbacks) {
    const prevBtn = paginationControls.querySelector('.pagination-prev');
    const nextBtn = paginationControls.querySelector('.pagination-next');
    const pageInput = paginationControls.querySelector('.pagination-page-input');

    let currentIndex = 0;

    prevBtn.addEventListener('click', () => {
      if (currentIndex > 0) {
        currentIndex--;
        callbacks.onPageChange(currentIndex);
      }
    });

    nextBtn.addEventListener('click', () => {
      if (currentIndex < totalItems - 1) {
        currentIndex++;
        callbacks.onPageChange(currentIndex);
      }
    });

    pageInput.addEventListener('change', e => {
      let pageNum = parseInt(e.target.value);
      if (isNaN(pageNum) || pageNum < 1) {
        pageNum = 1;
      } else if (pageNum > totalItems) {
        pageNum = totalItems;
      }
      currentIndex = pageNum - 1;
      callbacks.onPageChange(currentIndex);
    });

    pageInput.addEventListener('keydown', e => {
      if (e.key === 'Enter') {
        e.target.blur();
      }
    });
  }

  function createItemCard(item, isPurpleAiRule, oobeeAiQueryLabel, aiConfig) {
    const isGenAiSupportedRule = ['color-contrast', 'oobee-accessible-label', 'image-alt', 'listitem', 'link-in-text-block', 'target-size'].includes(aiConfig.ruleInCategory.rule);
    const showGenAiUI = window.oobeeGenAiFeatureEnabled && isGenAiSupportedRule;

    return createElementFromString(`
      <div>
        <div class="d-flex gap-3 flex-column">
        <h3>Where to find this issue</h3>
          ${item.screenshotPath ? createScreenshotSection(item.screenshotPath) : ''}
          ${item.xpath ? createXpathSection(item.xpath) : ''}
          ${createElementSection(item)}
          ${
            (() => {
              const showDetails = item.displayNeedsReview || ['color-contrast', 'color-contrast-enhanced', 'oobee-grading-text-contents', 'target-size', 'valid-lang', 'aria-valid-attr-value', 'aria-required-children', 'aria-prohibited-attr', 'aria-allowed-attr'].includes(aiConfig.ruleInCategory.rule);
              return showDetails && item.message
                ? `<div class="d-flex justify-content-between g-one">
            <div class="fw-semibold page-item-card-section-title">Details</div>
            <div class="page-item-card-section-content">
              ${generateItemMessageElement(item.displayNeedsReview || true, item.message)}
            </div>
          </div>`
                : '';
            })()
          }
          ${isPurpleAiRule ? createAiSuggestionSection(item, oobeeAiQueryLabel, aiConfig) : ''}
          ${showGenAiUI ? createGenAiSuggestFixSection(item, aiConfig) : ''}
        </div>
      </div>
    `);
  }

  function createScreenshotSection(screenshotPath) {
    return `
      <div class="hide-on-img-error">
        <div class="d-flex justify-content-between g-one modal-view">
          <div class="fw-semibold">Screenshot</div>
          <div class="page-item-card-section-content bg-grey-w-border">
            <img
              src="${screenshotPath}"
              onerror="this.onerror = null; this.closest('div.hide-on-img-error').remove();"
              alt="Screenshot of affected element" />
          </div>
        </div>
      </div>
    `;
  }

  function createXpathSection(xpath) {
    return `
      <div class="d-flex justify-content-between g-one modal-view">
        <div class="fw-semibold">Path</div>
        <div class="page-item-card-section-content">
          <div class="g-one path-container">
            ${xpath}
            <button
              aria-label="Copy path to clipboard"
              class="copy-button"
              data-bs-toggle="tooltip"
              data-bs-placement="top"
              data-bs-original-title="Copy"
            >
            <svg width="13" height="15" viewBox="0 0 13 15" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M3.33333 0H11.3333C12.0667 0 12.6667 0.6 12.6667 1.33333V10.6667H11.3333V1.33333H3.33333V0ZM1.33333 2.66667H8.66667C9.4 2.66667 10 3.26667 10 4V13.3333C10 14.0667 9.4 14.6667 8.66667 14.6667H1.33333C0.600001 14.6667 9.53674e-07 14.0667 9.53674e-07 13.3333V4C9.53674e-07 3.26667 0.600001 2.66667 1.33333 2.66667ZM1.33333 13.3333H8.66667V4H1.33333V13.3333Z" fill="#5735DF"/>
            </svg>
            </button>
          </div>
        </div>
      </div>
    `;
  }

  function createElementSection(item) {
    return `
      <div class="d-flex justify-content-between g-one modal-view">
        ${
          item.html
            ? `
          <div class="fw-semibold">HTML element</div>
          <pre class="page-item-card-section-content">
            <code class="language-html">
              ${htmlEscapeString(item.html)}
            </code>
          </pre>`
            : `
          <div class="fw-semibold">Location</div>
          <div class="page-item-card-section-content">
            ${item.page > 0 ? `Page ${item.page}` : 'Document'}
          </div>`
        }
      </div>
    `;
  }

  function createAiSuggestionSection(item, oobeeAiQueryLabel, aiConfig) {
    const { accordionDivToAppendAI, buttonDivForAiFeedback, aiErrorDiv, ruleInCategory } = aiConfig;

    let aiContent = '';
    if (oobeeAiQueryLabel.hasNetworkError) {
      aiContent = `
        <button
          id="${buttonDivForAiFeedback}"
          class="aiGenerateResponseButton"
          onClick="handleOfflinePurpleAi(
            '${ruleInCategory.rule}',
            '${accordionDivToAppendAI}',
            '${escapeHtmlStringForArg(item.html)}',
            '${buttonDivForAiFeedback}',
            '${aiErrorDiv}')"
        >
          Generate response
        </button>
        <div id="${aiErrorDiv}"></div>
      `;
    } else if (oobeeAiQueryLabel.label) {
      aiContent = `
        <button
          id="${buttonDivForAiFeedback}"
          class="aiGenerateResponseButton"
          onClick="getPurpleAiAnswer(
            '${ruleInCategory.rule}',
            '${accordionDivToAppendAI}',
            '${oobeeAiQueryLabel.label}',
            '${buttonDivForAiFeedback}',
            '${aiErrorDiv}')"
        >
          Generate response
        </button>
        <div id="${aiErrorDiv}"></div>
      `;
    } else {
      aiContent = `
        <span class="processAI">
          Processing AI suggestions, please check back later.
        </span>
      `;
    }

    return `
      <div class="d-flex g-one">
        <div class="fw-semibold page-item-card-section-title">AI suggestion</div>
        <div id="${accordionDivToAppendAI}" class="page-item-card-section-content">
          ${aiContent}
        </div>
      </div>
    `;
  }

  function createGenAiSuggestFixSection(item, aiConfig) {
    const { genAiAccordionDiv, genAiButtonDiv, genAiErrorDiv, ruleInCategory } = aiConfig;

    return `
      <div class="d-flex g-one genai-fix-section">
        <div class="fw-semibold page-item-card-section-title">Generative AI Fix</div>
        <div id="${genAiAccordionDiv}" class="page-item-card-section-content">
          <button
            id="${genAiButtonDiv}"
            class="genAiSuggestFixButton"
            onClick="generateGenAiSuggestFix(
              '${ruleInCategory.rule}',
              '${genAiAccordionDiv}',
              '${escapeHtmlStringForArg(item.html)}',
              '${genAiButtonDiv}',
              '${genAiErrorDiv}')"
          >
            Gen AI Suggest Fix
          </button>
          <div id="${genAiErrorDiv}"></div>
        </div>
      </div>
    `;
  }

  function setupCopyButton(itemCard, xpath) {
    const copyButtonElem = itemCard.getElementsByClassName('copy-button')[0];
    if (!copyButtonElem || !xpath) return;

    const copyTooltipItem = new bootstrap.Tooltip(copyButtonElem);
    const textToCopy = createElementFromString(`<textarea>${xpath}</textarea>`);

    copyButtonElem.onclick = event => {
      textToCopy.select();
      navigator.clipboard.writeText(textToCopy.value);

      copyButtonElem.setAttribute('data-bs-original-title', 'Copied');
      copyTooltipItem.update();
      copyTooltipItem.show();

      setTimeout(() => {
        copyButtonElem.setAttribute('data-bs-original-title', 'Copy');
        copyTooltipItem.update();
      }, 1500);
    };

    copyButtonElem.onmousedown = event => {
      event.preventDefault();
    };
  }

  // Legacy function name for backwards compatibility
  function buildExpandedRuleCategoryContentAccordian(
    accordionId,
    category,
    ruleInCategory,
    page,
    index,
  ) {
    buildItemCardsWithPagination(accordionId, category, ruleInCategory, page, index);
  }
</script>
