<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { DevModeEnvironmentKey } from '../../composables/useDevModeEnvironment'
import { useDevModePoEditor } from '../../composables/useDevModePoEditor'
import { useFdsI18n } from '../../plugin/useFdsI18n'
import FdsIcon from '../FdsIcon/FdsIcon.vue'
import FdsButtonMinor from '../Buttons/FdsButtonMinor/FdsButtonMinor.vue'
import FdsCheckbox from '../Form/FdsCheckbox/FdsCheckbox.vue'
import FdsRadio from '../Form/FdsRadio/FdsRadio.vue'
import FdsLabel from '../Typography/FdsLabel/FdsLabel.vue'
import type { DevModeOverlayToggle, DevModeQuickSettingType, DevModeRadioToggle } from './types'

const OVERLAY_OPEN_KEY = 'devModeOverlayOpen'

const props = withDefaults(
  defineProps<{
    environment?: DevModeEnvironmentKey | null
    toggles?: DevModeOverlayToggle[]
  }>(),
  {
    environment: null,
    toggles: () => [],
  },
)

const emit = defineEmits<{
  toggle: [payload: { key: string; value: boolean }]
  select: [payload: { key: string; group: string; value: string }]
  action: [payload: { key: string }]
}>()

const { i18n, locale, t, tCore } = useFdsI18n()
const { showingTranslationKeys, canToggleI18nKeys, setI18nKeysVisibility } = useDevModePoEditor()

const isOpen = ref(true)

try {
  const stored = localStorage.getItem(OVERLAY_OPEN_KEY)
  if (stored !== null) {
    isOpen.value = JSON.parse(stored)
  }
} catch {
  isOpen.value = true
}

watch(isOpen, (value) => {
  localStorage.setItem(OVERLAY_OPEN_KEY, JSON.stringify(value))
})

type I18nWithLocales = {
  availableLocales?: string[]
  global?: { availableLocales?: string[] }
}

const localeOptions = computed(() => {
  const i18nWithLocales = (i18n?.global ?? i18n) as I18nWithLocales | undefined
  const locales = i18nWithLocales?.availableLocales
  if (Array.isArray(locales) && locales.length > 1) {
    return [...new Set(locales.filter((entry) => typeof entry === 'string' && entry.length > 0))]
  }
  return []
})

const showLocaleSwitcher = computed(() => localeOptions.value.length > 1)

const localeLabel = (localeCode: string): string => {
  const normalized = localeCode.toLowerCase().split(/[-_]/)[0]
  if (normalized === 'sv') return t('FdsDevMode.overlay.localeSv')
  if (normalized === 'en') return t('FdsDevMode.overlay.localeEn')
  return localeCode
}

const setLocale = (localeCode: string) => {
  const localeRef = i18n?.global?.locale ?? i18n?.locale
  if (localeRef && typeof localeRef === 'object' && 'value' in localeRef) {
    localeRef.value = localeCode
  }
}

const isLocaleSelected = (localeCode: string): boolean => {
  const current = locale.value.toLowerCase().split(/[-_]/)[0]
  const candidate = localeCode.toLowerCase().split(/[-_]/)[0]
  return current === candidate
}

const toggleLabelKey = (toggle: DevModeOverlayToggle): string =>
  toggle.labelKey ?? `FdsDevMode.overlay.toggles.${toggle.key}`

const getToggleType = (toggle: DevModeOverlayToggle): DevModeQuickSettingType => toggle.type ?? 'check'

const isRadioToggle = (toggle: DevModeOverlayToggle): toggle is DevModeOverlayToggle & DevModeRadioToggle =>
  toggle.type === 'radio'

const checkToggles = computed(() => props.toggles.filter((toggle) => getToggleType(toggle) === 'check'))
const radioToggles = computed(() => props.toggles.filter(isRadioToggle))
const buttonToggles = computed(() => props.toggles.filter((toggle) => toggle.type === 'button'))

const handleRadioChange = (toggle: DevModeOverlayToggle & DevModeRadioToggle) => {
  emit('select', {
    key: toggle.key,
    group: toggle.group,
    value: toggle.value,
  })
}

const hasContent = computed(
  () =>
    checkToggles.value.length > 0 ||
    radioToggles.value.length > 0 ||
    buttonToggles.value.length > 0 ||
    canToggleI18nKeys.value ||
    showLocaleSwitcher.value,
)
</script>

<template>
  <div v-if="hasContent" class="absolute bottom-full right-0 mb-3 z-60 flex min-w-54 flex-col font-normal">
    <div v-if="isOpen" class="rounded-t-xl border border-b-0 border-gray-200 bg-white p-2 text-sm text-gray-900">
      <div class="flex flex-col gap-2">
        <div>
          <FdsCheckbox
            v-if="canToggleI18nKeys"
            :checked="showingTranslationKeys"
            @change="setI18nKeysVisibility"
            class="mb-0!"
          >
            {{ t('FdsDevMode.overlay.poeditor') }}
          </FdsCheckbox>

          <FdsCheckbox
            v-for="toggle in checkToggles"
            :key="`${toggle.key}-${toggle.checked}`"
            :checked="toggle.checked"
            class="mb-0!"
            @change="emit('toggle', { key: toggle.key, value: $event })"
          >
            {{ tCore(toggleLabelKey(toggle)) }}
          </FdsCheckbox>
        </div>

        <div v-if="radioToggles.length > 0">
          <FdsRadio
            v-for="toggle in radioToggles"
            :key="`${toggle.key}-${toggle.checked}`"
            :name="toggle.group"
            :value="toggle.value"
            :checked="toggle.checked"
            class="mb-0!"
            @change="handleRadioChange(toggle)"
          >
            {{ tCore(toggleLabelKey(toggle)) }}
          </FdsRadio>
        </div>

        <div v-if="buttonToggles.length > 0" class="flex flex-col gap-1">
          <FdsButtonMinor
            v-for="toggle in buttonToggles"
            :key="toggle.key"
            size="sm"
            block
            :text="tCore(toggleLabelKey(toggle))"
            @click="emit('action', { key: toggle.key })"
          />
        </div>
        <div v-if="showLocaleSwitcher">
          <FdsRadio
            v-for="localeCode in localeOptions"
            :key="localeCode"
            name="fds-dev-mode-locale"
            :value="localeCode"
            :checked="isLocaleSelected(localeCode)"
            @change="setLocale(localeCode)"
            class="mb-0!"
          >
            {{ localeLabel(localeCode) }}
          </FdsRadio>
        </div>
      </div>
    </div>

    <div
      class="rounded-xl border border-gray-200 bg-white text-sm text-gray-900"
      :class="{ 'rounded-t-none': isOpen }"
    >
      <button
        @click="isOpen = !isOpen"
        class="flex w-full cursor-pointer justify-between gap-2 px-3 py-2 active:bg-gray-100"
      >
        <FdsLabel class="mb-0!">{{ t('FdsDevMode.overlay.quickSettings') }}</FdsLabel>
        <FdsIcon :name="isOpen ? 'arrowUp' : 'arrowDown'" :size="20" class="fill-gray-700" />
      </button>
    </div>
  </div>
</template>
