import ICON_BACK from './arrow-back.svg'
import { google, apple } from './badges.js'

const { h, register, matter, preactHooks } = globalThis.ami
const { Asset, Box, Button, Heading, Link, RichText, SVG } = matter
const { useState, useEffect, useRef } = preactHooks

function arrayStartsWith (array, starter) {
  for (const [ii, element] of starter.entries()) {
    if (array[ii] !== element) {
      return false
    }
  }

  return true
}

function getBranch (branches, trail) {
  for (const branch of branches) {
    const branchPath = branch[0]
    if (arrayStartsWith(branchPath, trail)) {
      return branch
    }
  }

  return null
}

function getNextQuestion (branch, trail, questions) {
  const branchPath = branch[0]

  let ii = trail.length
  while (branchPath[ii] === null) {
    trail.push(null)
    ++ii
  }

  return questions[ii] // Will return undefined when end is reached.
}

function DecisionTree ({ src }) {
  if (!src) {
    return null // Exit early if src is missing
  }
  const [state, setState] = useState()
  const key = useRef(0)
  useEffect(() => {
    (async () => {
      const res = await fetch(src)
      const obj = await res.json()
      setState({ ...obj, trail: [] })
    })().catch(console.error)
  }, [src])

  if (!state) {
    return null
  }

  const branch = getBranch(state.branches, state.trail)
  const question = getNextQuestion(branch, state.trail, state.questions)
  const results = question ? null : branch[1].map(id => state.results[id])

  const handleAnswer = event => {
    event.preventDefault()
    const answer = event.target.textContent
    state.trail.push(answer)
    setState({ ...state })
    key.current++
  }

  const handleBack = event => {
    event.preventDefault()

    const removeNulls = () => {
      while (state.trail.at(-1) === null) {
        state.trail.pop()
      }
    }

    removeNulls()
    state.trail.pop()
    removeNulls()

    setState({ ...state })
    key.current++
  }

  return h('div',
    // Question.
    question && h(Box, { key: key.current, className: 'rounded-2xl bg-bga text-txa grid lg:grid-cols-2 gap-5 animate-fade' },
      h('div', { className: 'flex flex-col justify-center space-y-5' },
        h('div', { className: 'text-center' },
          h(Heading, { _level: 3 }, question.text)
        ),
        h('div', { className: 'flex justify-center lg:flex-nowrap flex-wrap gap-5' },
          question.answers.map(answer =>
            h(Button, {
              _model: { name: answer },
              _wide: true,
              onClick: handleAnswer
            })
          )
        ),
        state.trail.length > 0 && h('div', { className: 'text-center' },
          h(Link, {
            tabindex: 0,
            _model: { name: 'Back', icon: ICON_BACK },
            _variant: 'simple',
            className: 'cursor-pointer',
            onClick: handleBack,
            onkeydown: event => event.key === 'Enter' && handleBack(event)
          })
        )
      ),
      h('div', { className: 'overflow-hidden rounded-lg h-full' },
        h(Asset, {
          _tall: true,
          _model: {
            image: { src: question.asset }
          }
        })
      )
    ),
    // Recommendation.
    results && h('div', { className: 'grid lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-5 animate-fade' },
      results.map(result =>
        h(Result, result)
      )
    )
  )
}

function Result ({ title, text, link, cta, asset, appStoreText, appStoreUrl, playStoreText, playStoreUrl }) {
  return h('div', { className: 'bg-bga text-txa h-full rounded-2xl overflow-hidden' },
    asset && h('div',
      h('img', { src: asset })
    ),
    h(Box, { className: 'bg-bga text-txa w-full' },
      h(Heading, { _level: '3' }, title),
      h(RichText, text),

      link && cta && h(Link, { _model: { name: cta, value: link }, _variant: 'full', target: '_blank' }),

      (appStoreUrl || playStoreUrl) && h('div', { className: 'flex gap-5 max-h-16' },
        h(StoreButton, { name: 'App Store', url: appStoreUrl, text: appStoreText, svgGenerator: apple }),
        h(StoreButton, { name: 'Google Play', url: playStoreUrl, text: playStoreText, svgGenerator: google })
      )
    )
  )
}

function StoreButton ({ name, url, text, svgGenerator }) {
  if (!url) {
    return null
  }

  return h(Link, { _model: { name, value: url }, 'aria-label': `${text} ${name}`, className: 'h-16' },
    h(SVG, { _tall: true, _model: { src: svgGenerator(text) }, className: 'h-12 w-auto' })
  )
}

register(DecisionTree, 'decision-tree')
