import { sortBy } from 'lodash-es'
import { ARRAY_SECTION_SIZE } from '../constants.js'

/**
 * Create sections that can be expanded.
 * Used to display a button like "Show items 100-200"
 *
 * @param {number} startIndex
 * @param {number} endIndex
 * @return {Section[]}
 */
export function getExpandItemsSections(startIndex, endIndex) {
  // expand the start of the section
  const section1 = {
    start: startIndex,
    end: Math.min(nextRoundNumber(startIndex), endIndex)
  }

  // expand the middle of the section
  const start2 = Math.max(currentRoundNumber((startIndex + endIndex) / 2), startIndex)
  const section2 = {
    start: start2,
    end: Math.min(nextRoundNumber(start2), endIndex)
  }

  // expand the end of the section
  const currentIndex = currentRoundNumber(endIndex)
  const previousIndex = currentIndex === endIndex ? currentIndex - ARRAY_SECTION_SIZE : currentIndex
  const section3 = {
    start: Math.max(previousIndex, startIndex),
    end: endIndex
  }

  const sections = [section1]

  const showSection2 = section2.start >= section1.end && section2.end <= section3.start
  if (showSection2) {
    sections.push(section2)
  }

  const showSection3 = section3.start >= (showSection2 ? section2.end : section1.end)
  if (showSection3) {
    sections.push(section3)
  }

  return sections
}

/**
 * Sort and merge a list with sections
 * @param {Section[]} sections
 * @return {Section[]}
 */
export function mergeSections(sections) {
  const sortedSections = sortBy(sections, (section) => section.start)

  const mergedSections = [sortedSections[0]]

  for (let sortedIndex = 0; sortedIndex < sortedSections.length; sortedIndex++) {
    const mergedIndex = mergedSections.length - 1
    const previous = mergedSections[mergedIndex]
    const current = sortedSections[sortedIndex]

    if (current.start <= previous.end) {
      // there is overlap -> replace the previous item
      mergedSections[mergedIndex] = {
        start: Math.min(previous.start, current.start),
        end: Math.max(previous.end, current.end)
      }
    } else {
      // no overlap, just add the item
      mergedSections.push(current)
    }
  }

  return mergedSections
}

// TODO: write unit test
export function inVisibleSection(sections, index) {
  return sections.some((section) => {
    return index >= section.start && index < section.end
  })
}

export function nextRoundNumber(index) {
  return currentRoundNumber(index) + ARRAY_SECTION_SIZE
}

export function currentRoundNumber(index) {
  return Math.floor(index / ARRAY_SECTION_SIZE) * ARRAY_SECTION_SIZE
}
