<template>
  <div class="w100 flex column">
    <div class="flex row w100">
      <q-input
        v-model="search"
        clearable
        clear-icon="close"
        :placeholder="$t('settings__timezone_search')"
        dense
        class="col-grow"
      >
        <template #prepend>
          <q-icon name="mdi-magnify" />
        </template>
      </q-input>
    </div>

    <q-list class="q-gutter-y-sm q-my-sm">
      <q-btn
        v-for="tz in displayTimeZones"
        :key="tz.value"
        flat
        no-caps
        dense
        class="w100"
        align="left"
        @click="selectTz(tz)"
        :class="isSelected(tz.value) ? 'text-primary' : ''"
      >
        <div class="flex w100 no-wrap">
          <q-icon
            :name="isSelected(tz.value) ? 'mdi-check' : ''"
            color="primary"
            class="q-pr-sm"
          />
          <div class="flex row no-wrap justify-between w100">
            <div>
              <span class="text-grey text-weight-regular">{{ tz.continent + ' / ' }}</span>
              <span>{{ tz.city + ' ' }}</span>
            </div>
            <span class="text-grey text-weight-regular">{{ tz.offsetDisplay }}</span>
          </div>
        </div>
      </q-btn>
    </q-list>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watchEffect } from 'vue'

interface TimeZone {
  value: string
  continent: string
  city: string
  offsetDisplay: string
  offsetHours: number
}

defineProps<{
  locale: string
}>()

const modelValue = defineModel<{ tz: string; offset: number, offsetString: string }>({
  required: true
})

const search = ref('')
const timeZonesBase = Intl.supportedValuesOf('timeZone')
const timeZones = ref<TimeZone[]>([])

watchEffect(() => {
  const date = Date.now()
  
  timeZones.value = timeZonesBase.map((tz) => {
    const [continent, ...cityParts] = tz.split('/')
    const city = cityParts.join('/').replace(/_/g, ' ')
    
    const formatter = new Intl.DateTimeFormat('en', {
      timeZone: tz,
      timeZoneName: 'longOffset'
    })

    const offsetPart = formatter
      .formatToParts(date)
      .find(part => part.type === 'timeZoneName')?.value || 'UTC'
    
    const cleanOffset = offsetPart.replace(/^GMT|^UTC/, '') || '+00:00'
    let sign = 1
    let offsetString = cleanOffset

    if (cleanOffset.startsWith('-')) {
      sign = -1
      offsetString = cleanOffset.substring(1)
    } else if (cleanOffset.startsWith('+')) {
      offsetString = cleanOffset.substring(1)
    }

    const [hours = '0', minutes = '0'] = offsetString.split(':')
    const totalHours = sign * (parseInt(hours) + parseInt(minutes) / 60)
    
    const absHours = Math.abs(parseInt(hours))
    const absMinutes = Math.abs(parseInt(minutes))
    const displaySign = sign === -1 ? '-' : '+'
    const offsetDisplay = `${displaySign}${String(absHours).padStart(2, '0')}:${String(absMinutes).padStart(2, '0')}`

    return {
      value: tz,
      continent: continent?.replace(/_/g, ' ') || '',
      city: city,
      offsetDisplay,
      offsetHours: totalHours
    }
  })
})

const displayTimeZones = computed(() => {
  if (!search.value || !(search.value && search.value.trim())) return timeZones.value
  const searchValue = search.value.trim().toLowerCase()

  return timeZones.value.filter(
    el =>
      el.continent.toLowerCase().includes(searchValue) ||
      el.city.toLowerCase().includes(searchValue) ||
      el.offsetDisplay.includes(searchValue) ||
      el.offsetDisplay.replace(':', '').includes(searchValue)
    )
})

const isSelected = (value: string) => {
  return modelValue.value.tz === value
}

const selectTz = (tz: TimeZone) => {
  modelValue.value = { tz: tz.value, offset: tz.offsetHours, offsetString: tz.offsetDisplay }
}
</script>

<style scoped>
</style>
