<script setup lang="ts">
import { computed, ref } from 'vue';
import {
  countryFlagUrl,
  countryCrestUrl,
  countryDisplayName,
  countryOptionLabel,
  getBuiltinCountry,
  hasCountryCrest,
  searchBuiltinCountries,
  type BuiltinCountry,
} from '../../data/builtinCountries';
import { useAdminLocale } from '../../composables/useAdminLocale';

const props = defineProps<{
  modelValue: string;
  size?: 'small' | 'default' | 'large';
  disabled?: boolean;
  hidePreview?: boolean;
}>();

const emit = defineEmits<{
  'update:modelValue': [code: string];
  pick: [country: BuiltinCountry];
}>();

const { t, locale } = useAdminLocale();

const filterKeyword = ref('');
const options = computed(() => searchBuiltinCountries(filterKeyword.value, locale.value));

const selected = computed(() => getBuiltinCountry(props.modelValue));

function optionLabel(c: BuiltinCountry) {
  return countryOptionLabel(c, locale.value);
}

function onFilter(q: string) {
  filterKeyword.value = q;
}

function onChange(code: string | undefined) {
  const value = code ?? '';
  emit('update:modelValue', value);
  const country = getBuiltinCountry(value);
  if (country) emit('pick', country);
}
</script>

<template>
  <div class="country-flag-select">
    <el-select
      :model-value="modelValue || undefined"
      :size="size ?? 'small'"
      :disabled="disabled"
      filterable
      clearable
      :filter-method="onFilter"
      :placeholder="t('outright.country_ph')"
      class="country-select"
      @update:model-value="onChange"
      @visible-change="(v: boolean) => { if (v) filterKeyword = ''; }"
    >
      <el-option
        v-for="c in options"
        :key="c.code"
        :label="optionLabel(c)"
        :value="c.code"
      >
        <div class="country-option">
          <img :src="countryFlagUrl(c)" alt="" class="country-option-flag" loading="lazy" />
          <img
            v-if="hasCountryCrest(c)"
            :src="countryCrestUrl(c)"
            alt=""
            class="country-option-crest"
            loading="lazy"
          />
          <span class="country-option-name">{{ countryDisplayName(c, locale) }}</span>
          <span class="country-option-code">{{ c.code }}</span>
        </div>
      </el-option>
    </el-select>
    <img
      v-if="selected && !hidePreview"
      :src="countryFlagUrl(selected)"
      alt=""
      class="country-preview"
      loading="lazy"
    />
  </div>
</template>

<style scoped>
.country-flag-select {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-width: 0;
}

.country-select {
  flex: 1;
  min-width: 0;
}

.country-preview {
  width: 32px;
  height: 22px;
  object-fit: cover;
  border-radius: 2px;
  flex-shrink: 0;
  background: #222;
}

.country-option {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.country-option-flag {
  width: 24px;
  height: 16px;
  object-fit: cover;
  border-radius: 2px;
  flex-shrink: 0;
}

.country-option-crest {
  width: 22px;
  height: 22px;
  object-fit: contain;
  flex-shrink: 0;
}

.country-option-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}

.country-option-code {
  font-size: 11px;
  color: #888;
  flex-shrink: 0;
}
</style>
