<script setup lang="ts">
/**
 * Props-driven timezone picker composition. Searchable combobox over
 * every IANA timezone reported by the runtime (`Intl.supportedValuesOf`).
 * Falls back to a curated list when `Intl.supportedValuesOf` is missing
 * (older jsdom).
 *
 *   <TimezonePicker v-model="tz" label="Timezone" />
 */
import { computed, ref } from "vue"
import { Globe } from "@lucide/vue"
import {
  Combobox,
  ComboboxAnchor,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxItemIndicator,
} from "@/components/ui/combobox"
import { FieldFrame } from "@/components/ui/field-frame"

export interface TimezonePickerProps {
  modelValue?: string | null
  id?: string
  name?: string
  label?: string
  hideLabel?: boolean
  placeholder?: string
  required?: boolean
  readonly?: boolean
  disabled?: boolean
  helpText?: string
  errors?: string[]
}

withDefaults(defineProps<TimezonePickerProps>(), {
  errors: () => [],
})

const model = defineModel<string | null>("modelValue")

const query = ref<string>("")

const timezones = computed<string[]>(() => {
  const intl = Intl as unknown as {
    supportedValuesOf?: (key: string) => string[]
  }
  if (typeof intl.supportedValuesOf === "function") {
    try {
      return intl.supportedValuesOf("timeZone")
    } catch {
      return []
    }
  }
  return [
    "UTC",
    "America/New_York",
    "America/Chicago",
    "America/Denver",
    "America/Los_Angeles",
    "Europe/London",
    "Europe/Paris",
    "Europe/Berlin",
    "Asia/Tokyo",
    "Asia/Shanghai",
    "Australia/Sydney",
  ]
})

const filtered = computed<string[]>(() => {
  const q = query.value.trim().toLowerCase()
  if (!q) {
    return timezones.value.slice(0, 200)
  }
  return timezones.value
    .filter((tz) => tz.toLowerCase().includes(q))
    .slice(0, 200)
})

function onSelect(value: unknown): void {
  const next = typeof value === "string" ? value : ""
  model.value = next
}
</script>

<template>
  <FieldFrame
    :label="label"
    :required="required"
    :hide-label="hideLabel"
    :for="id"
    :help-text="helpText"
    :errors="errors"
  >
    <Combobox
      :model-value="model ?? ''"
      :disabled="disabled"
      @update:model-value="onSelect"
    >
      <ComboboxAnchor
        :data-element-name="name ?? undefined"
        :data-readonly="readonly || undefined"
      >
        <Globe class="mr-2 size-4 shrink-0 opacity-50" />
        <ComboboxInput
          v-model="query"
          :placeholder="placeholder ?? 'Select a timezone…'"
          :readonly="readonly"
          :required="required"
        />
      </ComboboxAnchor>
      <ComboboxContent>
        <ComboboxEmpty>No timezones match.</ComboboxEmpty>
        <ComboboxItem v-for="tz in filtered" :key="tz" :value="tz">
          <ComboboxItemIndicator />
          {{ tz }}
        </ComboboxItem>
      </ComboboxContent>
    </Combobox>
  </FieldFrame>
</template>
