import { useConfig } from 'domains/config/hooks'
import { useI18n } from 'domains/i18n/hooks'
import TranslationOption from 'domains/translations/components/options-dialog/translation-option'
import { useTranslations } from 'domains/translations/hooks'
import type { Language } from 'domains/translations/translations.types'
import { className } from 'lib/css'
import { useMemo } from 'preact/compat'
import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
import { sourceTypes } from 'ui/utils/seamly-utils'

type TranslationOptionsProps = {
  onChange: () => void
  describedById?: string
}

type LanguageType = {
  locale?: string
  nativeName?: string
  checked: boolean
  isOriginal: boolean
}

const isChecked = (language, currentLocale, isOriginal): boolean =>
  currentLocale === language.locale || (!currentLocale && isOriginal)

const TranslationOptions = ({
  onChange,
  describedById,
}: TranslationOptionsProps) => {
  const {
    context: { contentLocale },
  } = useConfig()

  const { t } = useI18n()
  const { languages, currentLocale, enableTranslations, disableTranslations } =
    useTranslations()
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()

  const handleChange = (locale?: Language['locale']) => () => {
    if (!locale) return
    if (locale === currentLocale || contentLocale === locale) {
      disableTranslations()
    } else {
      enableTranslations(locale, sourceTypes.translationChoice)
    }

    onChange()
    focusSkiplinkTarget()
  }

  const { primaryLanguages, remainingLanguages } = useMemo(
    () =>
      languages.reduce(
        (acc, language) => {
          const isOriginal = language.locale === contentLocale
          const checked = isChecked(language, currentLocale, isOriginal)

          if (language.locale !== contentLocale) {
            acc.remainingLanguages.push({ ...language, checked, isOriginal })
          }

          const selectedIdx = acc.remainingLanguages.findIndex(
            (l) => l.locale === currentLocale,
          )

          if (isOriginal || (checked && selectedIdx > 4)) {
            acc.primaryLanguages.push({ ...language, checked, isOriginal })
          }

          return acc
        },
        {
          primaryLanguages: [],
          remainingLanguages: [],
        } as {
          primaryLanguages: LanguageType[]
          remainingLanguages: LanguageType[]
        },
      ),
    [currentLocale, contentLocale, languages],
  )

  return (
    <ul
      aria-describedby={describedById}
      role="listbox"
      tabIndex={-1}
      className={className('translation-options')}
    >
      {primaryLanguages.map(
        ({ locale, nativeName, checked, isOriginal }, idx) => (
          <TranslationOption
            key={locale}
            id={locale}
            label={nativeName}
            checked={checked}
            description={
              isOriginal ? t('translations.settings.original') : undefined
            }
            onChange={handleChange(locale)}
            itemClassName={className({
              'translation-options__item--original': isOriginal,
              'translation-options__item--selected': checked && idx !== 0,
            })}
          />
        ),
      )}
      {remainingLanguages.map(({ locale, nativeName, checked, isOriginal }) => (
        <TranslationOption
          key={locale}
          id={locale}
          label={nativeName}
          checked={checked}
          description={
            isOriginal ? t('translations.settings.original') : undefined
          }
          onChange={handleChange(locale)}
        />
      ))}
    </ul>
  )
}

export default TranslationOptions
