<template>
  <el-select
    v-model="selectedValue"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :multiple="multiple"
    :filterable="filterable"
    :remote="remote"
    :remote-method="remoteMethod"
    :loading="loading"
    :size="size"
    @change="handleChange"
    @visible-change="handleVisibleChange"
  >
    <el-option
      v-for="item in packageList"
      :key="item.id"
      :label="item.packageName"
      :value="item.id"
    >
      <div class="package-option">
        <span class="package-name">{{ item.packageName }}</span>
        <span class="package-info">
          {{ formatFlow(item.totalFlow) }} / {{ formatMoney(item.price) }}
        </span>
      </div>
    </el-option>
  </el-select>
</template>

<script setup lang="ts">
  import { ref, computed, onMounted } from 'vue'
  import type { Package } from '@/types/api'
  import { formatFlow, formatMoney } from '@/utils/business'

  interface Props {
    modelValue?: string | number | (string | number)[]
    placeholder?: string
    clearable?: boolean
    disabled?: boolean
    multiple?: boolean
    filterable?: boolean
    remote?: boolean
    size?: 'large' | 'default' | 'small'
    // 预加载的套餐列表
    packages?: Package[]
    // 远程搜索方法
    fetchMethod?: (query: string) => Promise<Package[]>
  }

  interface Emits {
    (e: 'update:modelValue', value: string | number | (string | number)[] | undefined): void
    (e: 'change', value: string | number | (string | number)[] | undefined): void
  }

  const props = withDefaults(defineProps<Props>(), {
    placeholder: '请选择套餐',
    clearable: true,
    disabled: false,
    multiple: false,
    filterable: true,
    remote: false,
    size: 'default'
  })

  const emit = defineEmits<Emits>()

  const loading = ref(false)
  const packageList = ref<Package[]>([])

  const selectedValue = computed({
    get: () => props.modelValue,
    set: (val) => {
      emit('update:modelValue', val)
    }
  })

  const handleChange = (value: string | number | (string | number)[] | undefined) => {
    emit('change', value)
  }

  const handleVisibleChange = (visible: boolean) => {
    if (visible && !props.remote && packageList.value.length === 0) {
      loadPackages()
    }
  }

  const loadPackages = async () => {
    if (props.packages) {
      packageList.value = props.packages
    } else if (props.fetchMethod) {
      loading.value = true
      try {
        packageList.value = await props.fetchMethod('')
      } finally {
        loading.value = false
      }
    }
  }

  const remoteMethod = async (query: string) => {
    if (!props.fetchMethod) return

    loading.value = true
    try {
      packageList.value = await props.fetchMethod(query)
    } finally {
      loading.value = false
    }
  }

  onMounted(() => {
    if (props.packages) {
      packageList.value = props.packages
    }
  })
</script>

<style scoped lang="scss">
  .package-option {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .package-name {
      font-weight: 500;
      color: var(--el-text-color-primary);
    }

    .package-info {
      margin-left: 12px;
      font-size: 12px;
      color: var(--el-text-color-secondary);
    }
  }
</style>
