<template>
  <div class="phone-input-wrapper">
    <v-text-field
      :model-value="displayValue"
      @update:model-value="updatePhone"
      :label="label"
      :variant="variant"
      :density="density"
      :rules="rules"
      :required="required"
      :disabled="disabled"
      :readonly="readonly"
      :clearable="clearable"
      :hide-details="hideDetails"
      :error-messages="errorMessages"
    >
      <template #prepend-inner>
        <v-menu
          v-model="countryMenu"
          :close-on-content-click="true"
          location="bottom"
        >
          <template v-slot:activator="{ props }">
            <v-btn
              v-bind="props"
              variant="text"
              size="small"
              class="country-selector"
              :disabled="disabled || readonly"
            >
              <span class="country-flag">{{ selectedCountry.flag }}</span>
              <span class="country-code">{{ selectedCountry.dialCode }}</span>
              <v-icon end size="small">mdi-menu-down</v-icon>
            </v-btn>
          </template>
          <v-list density="compact" max-height="300">
            <v-list-item
              v-for="country in filteredCountries"
              :key="country.iso2"
              @click="selectCountry(country)"
              :title="`${country.flag} ${country.name} (${country.dialCode})`"
            >
            </v-list-item>
          </v-list>
        </v-menu>
      </template>
    </v-text-field>
  </div>
</template>

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

interface Country {
  name: string;
  iso2: string;
  dialCode: string;
  flag: string;
}

interface Props {
  modelValue?: string;
  label?: string;
  variant?: 'flat' | 'elevated' | 'tonal' | 'outlined' | 'plain' | 'underlined' | 'solo' | 'solo-inverted' | 'solo-filled';
  density?: 'default' | 'comfortable' | 'compact';
  rules?: any[];
  required?: boolean;
  disabled?: boolean;
  readonly?: boolean;
  clearable?: boolean;
  hideDetails?: boolean | 'auto';
  errorMessages?: string | string[];
  defaultCountry?: string;
  preferredCountries?: string[];
}

const props = withDefaults(defineProps<Props>(), {
  label: 'Phone Number',
  variant: 'outlined',
  density: 'comfortable',
  defaultCountry: 'US',
  preferredCountries: () => ['US', 'FR', 'ES', 'PT', 'GB']
});

const emit = defineEmits<{
  'update:modelValue': [value: string];
}>();

// Countries data
const countries: Country[] = [
  { name: 'United States', iso2: 'US', dialCode: '+1', flag: '🇺🇸' },
  { name: 'United Kingdom', iso2: 'GB', dialCode: '+44', flag: '🇬🇧' },
  { name: 'France', iso2: 'FR', dialCode: '+33', flag: '🇫🇷' },
  { name: 'Spain', iso2: 'ES', dialCode: '+34', flag: '🇪🇸' },
  { name: 'Portugal', iso2: 'PT', dialCode: '+351', flag: '🇵🇹' },
  { name: 'Germany', iso2: 'DE', dialCode: '+49', flag: '🇩🇪' },
  { name: 'Italy', iso2: 'IT', dialCode: '+39', flag: '🇮🇹' },
  { name: 'Netherlands', iso2: 'NL', dialCode: '+31', flag: '🇳🇱' },
  { name: 'Belgium', iso2: 'BE', dialCode: '+32', flag: '🇧🇪' },
  { name: 'Switzerland', iso2: 'CH', dialCode: '+41', flag: '🇨🇭' },
  { name: 'Austria', iso2: 'AT', dialCode: '+43', flag: '🇦🇹' },
  { name: 'Sweden', iso2: 'SE', dialCode: '+46', flag: '🇸🇪' },
  { name: 'Norway', iso2: 'NO', dialCode: '+47', flag: '🇳🇴' },
  { name: 'Denmark', iso2: 'DK', dialCode: '+45', flag: '🇩🇰' },
  { name: 'Finland', iso2: 'FI', dialCode: '+358', flag: '🇫🇮' },
  { name: 'Poland', iso2: 'PL', dialCode: '+48', flag: '🇵🇱' },
  { name: 'Greece', iso2: 'GR', dialCode: '+30', flag: '🇬🇷' },
  { name: 'Ireland', iso2: 'IE', dialCode: '+353', flag: '🇮🇪' },
  { name: 'Canada', iso2: 'CA', dialCode: '+1', flag: '🇨🇦' },
  { name: 'Australia', iso2: 'AU', dialCode: '+61', flag: '🇦🇺' },
  { name: 'New Zealand', iso2: 'NZ', dialCode: '+64', flag: '🇳🇿' },
  { name: 'Japan', iso2: 'JP', dialCode: '+81', flag: '🇯🇵' },
  { name: 'China', iso2: 'CN', dialCode: '+86', flag: '🇨🇳' },
  { name: 'India', iso2: 'IN', dialCode: '+91', flag: '🇮🇳' },
  { name: 'Brazil', iso2: 'BR', dialCode: '+55', flag: '🇧🇷' },
  { name: 'Mexico', iso2: 'MX', dialCode: '+52', flag: '🇲🇽' },
  { name: 'South Africa', iso2: 'ZA', dialCode: '+27', flag: '🇿🇦' },
];

const countryMenu = ref(false);
const localNumber = ref('');
const selectedCountry = ref<Country>(
  countries.find(c => c.iso2 === props.defaultCountry) || countries[0]
);

// Sort countries with preferred ones first
const filteredCountries = computed(() => {
  const preferred = countries.filter(c => props.preferredCountries.includes(c.iso2));
  const others = countries.filter(c => !props.preferredCountries.includes(c.iso2));
  return [...preferred, ...others];
});

// Display value (local number without country code)
const displayValue = computed(() => localNumber.value);

// Parse initial value
watch(() => props.modelValue, (newValue) => {
  if (newValue) {
    // Find matching country code
    const country = countries.find(c => newValue.startsWith(c.dialCode));
    if (country) {
      selectedCountry.value = country;
      localNumber.value = newValue.slice(country.dialCode.length);
    } else {
      // Default to current country if no match
      localNumber.value = newValue;
    }
  } else {
    localNumber.value = '';
  }
}, { immediate: true });

// Update phone number
const updatePhone = (value: string) => {
  localNumber.value = value;
  if (value) {
    emit('update:modelValue', selectedCountry.value.dialCode + value);
  } else {
    emit('update:modelValue', '');
  }
};

// Select country
const selectCountry = (country: Country) => {
  selectedCountry.value = country;
  countryMenu.value = false;
  if (localNumber.value) {
    emit('update:modelValue', country.dialCode + localNumber.value);
  }
};
</script>

<style scoped>
.phone-input-wrapper {
  width: 100%;
}

.country-selector {
  padding: 0 8px;
  min-width: auto;
  height: auto;
}

.country-flag {
  font-size: 1.2rem;
  margin-right: 4px;
}

.country-code {
  font-size: 0.875rem;
  margin-right: 4px;
}

:deep(.v-field__prepend-inner) {
  padding-top: 0 !important;
}
</style>
