import { useState } from 'preact/hooks'
import { Button } from '../atoms/button.js'
import { Card } from '../atoms/card.js'
import { Heading } from '../atoms/heading.js'
import { Popup } from '../atoms/popup.js'
import { RichText } from '../atoms/rich-text.js'
import { Time } from '../atoms/time.js'
import { Asset } from '../molecules/asset.js'
import { Links } from '../molecules/links.js'
import { PromoText } from '../molecules/promo-text.js'
import { ValidationError } from '../routing/error-handler.js'
import h from '../shared/h.js'
import { NAVIGATION_CLOSE } from '../shared/icons.js'
import t from '../shared/t.js'
import { Fragment } from 'preact'

export function FilteredItem ({ _model, _variant, ...props }) {
  if (!_model.title) {
    throw new ValidationError()
  }

  const Component = { tags: WithTags, popup: WithPopup, links: WithLinks }[_variant] || Default
  return Component({ _model, ...props })
}

function Default ({ _model, ...props }) {
  return h('div', { ...props, className: 'h-full' },
    h(CardWrapper, { _model },
      h(BasicContent, { _model: { ..._model, links: [], tags: [] } },
        h(Labels, { _model })
      )
    )
  )
}

function WithTags ({ _model, ...props }) {
  const tags = _model.tags.map(tag => ({ name: tag.value }))
  return h('div', { ...props, className: 'h-full' },
    h(CardWrapper, { _model },
      h(BasicContent, { _model: { ..._model, links: [], tags } })
    )
  )
}

function WithLinks ({ _model, ...props }) {
  return h('div', { ...props, className: 'h-full' },
    h(StaticCard, { _model },
      h(BasicContent, { _model: { ..._model, tags: [] } },
        h(Labels, { _model })
      )
    )
  )
}

function WithPopup ({ _model, ...props }) {
  const [showPopup, setShowPopup] = useState(false)

  return h('div', { ...props, className: 'h-full' },
    h(Card, {
      _model: { value: '#' },
      role: 'button',
      onClick (event) {
        setShowPopup(true)
        event.preventDefault()
      },
      children: h(BasicContent, { _model: { ..._model, text: null, links: [], tags: [] } },
        h(Labels, { _model })
      )
    }),
    h(Popup, {
      _color: props._color,
      _layout: 'toast',
      _show: showPopup,
      onKeyDown (event) {
        if (event.key === 'Escape') {
          setShowPopup(false)
          event.preventDefault()
        }
      },
      children: h('div', { className: 'grid gap-5 grid-cols-2 sm:grid-cols-1' },
        _model.asset?.src && h('div', { className: 'space-y-5 sm:hidden' },
          h('div', { className: 'rounded-xl overflow-hidden' },
            h(Asset, { _model })
          ),
          h('div',
            h(Labels, { _model })
          )
        ),
        h('div', { className: 'space-y-5' },
          h('div', { className: 'flex gap-2' },
            h('div', { className: 'grow' },
              h(Heading, { _level: 3 }, _model.title),
              _model.date && h(Time, { _time: _model.date })
            ),
            h('div', { className: 'shrink-0' },
              h(Button, {
                _variant: 'plain',
                _textless: true,
                _size: 'xs',
                _model: {
                  icon: NAVIGATION_CLOSE,
                  name: t('Close')
                },
                onClick: () => setShowPopup(false)
              })
            )
          ),
          _model.asset?.src && h('div', { className: 'rounded-xl overflow-hidden lg:hidden md:hidden' },
            h(Asset, { _model })
          ),
          h(RichText, _model.text),
          h(Links, { _model })
        )
      )
    })
  )
}

function BasicContent ({ _model, children }) {
  return h('div', { className: 'flex flex-col h-full' },
    Boolean(_model.asset.src) && h(Asset, { _model }),
    h(PromoText, { _model }),
    children
  )
}

function Labels ({ _model }) {
  const { tags } = _model
  if (!tags || tags.length === 0) {
    return null
  }

  const labels = {}
  for (const tag of tags) {
    labels[tag.name] ||= []
    labels[tag.name].push(tag.value)
  }

  const labelEntries = Object.entries(labels)

  return h(Fragment,
    h('div', { className: 'grow' }), // Pushes labels to the bottom.
    h('div', { className: 'px-6 pb-6' },
      h('hr', { className: 'mb-2 w-6 h-1 bg-bgb' }),
      h('div', { className: 'space-y-1' }, labelEntries.map(([name, values]) =>
        h('dl', { className: 'col-span-1 text-sm flex gap-2' },
          h('dt', { className: 'font-bold basis-24 grow-0 shrink-0' }, `${name}`),
          h('dd', values.join(', '))
        )
      ))
    )
  )
}

function StaticCard ({ _color, ...props }) {
  return h('div', { ...props, _color, className: 'bg-bga text-txa h-full rounded-2xl overflow-hidden flex flex-col' })
}

function CardWrapper ({ _model, children }) {
  const linkModel = { name: _model.title, value: _model.links[0]?.value }
  const hasLink = Boolean(_model.links[0]?.value)
  return h(hasLink ? Card : StaticCard, { _model: linkModel, children })
}
