/**
 * @typedef {import('mdast').List} List
 * @typedef {import('../types.js').Handle} Handle
 */

import {containerFlow} from '../util/container-flow.js'
import {checkBullet} from '../util/check-bullet.js'
import {checkBulletOther} from '../util/check-bullet-other.js'
import {checkBulletOrdered} from '../util/check-bullet-ordered.js'
import {checkBulletOrderedOther} from '../util/check-bullet-ordered-other.js'
import {checkRule} from '../util/check-rule.js'

/**
 * @type {Handle}
 * @param {List} node
 */
export function list(node, parent, context, safeOptions) {
  const exit = context.enter('list')
  const bulletCurrent = context.bulletCurrent
  /** @type {string} */
  let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context)
  /** @type {string} */
  const bulletOther = node.ordered
    ? checkBulletOrderedOther(context)
    : checkBulletOther(context)
  const bulletLastUsed = context.bulletLastUsed
  let useDifferentMarker = false

  if (
    parent &&
    // Explicit `other` set.
    (node.ordered
      ? context.options.bulletOrderedOther
      : context.options.bulletOther) &&
    bulletLastUsed &&
    bullet === bulletLastUsed
  ) {
    useDifferentMarker = true
  }

  if (!node.ordered) {
    const firstListItem = node.children ? node.children[0] : undefined

    // If there’s an empty first list item directly in two list items,
    // we have to use a different bullet:
    //
    // ```markdown
    // * - *
    // ```
    //
    // …because otherwise it would become one big thematic break.
    if (
      // Bullet could be used as a thematic break marker:
      (bullet === '*' || bullet === '-') &&
      // Empty first list item:
      firstListItem &&
      (!firstListItem.children || !firstListItem.children[0]) &&
      // Directly in two other list items:
      context.stack[context.stack.length - 1] === 'list' &&
      context.stack[context.stack.length - 2] === 'listItem' &&
      context.stack[context.stack.length - 3] === 'list' &&
      context.stack[context.stack.length - 4] === 'listItem' &&
      // That are each the first child.
      context.indexStack[context.indexStack.length - 1] === 0 &&
      context.indexStack[context.indexStack.length - 2] === 0 &&
      context.indexStack[context.indexStack.length - 3] === 0
    ) {
      useDifferentMarker = true
    }

    // If there’s a thematic break at the start of the first list item,
    // we have to use a different bullet:
    //
    // ```markdown
    // * ---
    // ```
    //
    // …because otherwise it would become one big thematic break.
    if (checkRule(context) === bullet && firstListItem) {
      let index = -1

      while (++index < node.children.length) {
        const item = node.children[index]

        if (
          item &&
          item.type === 'listItem' &&
          item.children &&
          item.children[0] &&
          item.children[0].type === 'thematicBreak'
        ) {
          useDifferentMarker = true
          break
        }
      }
    }
  }

  if (useDifferentMarker) {
    bullet = bulletOther
  }

  context.bulletCurrent = bullet
  const value = containerFlow(node, context, safeOptions)
  context.bulletLastUsed = bullet
  context.bulletCurrent = bulletCurrent
  exit()
  return value
}
