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

import { Avatar, Drawer, Empty, Input, Spin } from 'ant-design-vue';

import { salespersonOptionsApi } from '#/views/business/store/settings/api';
import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';

const props = withDefaults(
  defineProps<{
    excludeId?: number;
    initialSelected?: { avatar?: string; id?: number; nick_name?: string; phone?: string } | null;
    modelValue?: number;
    storeId?: number;
  }>(),
  {
    modelValue: 0,
    excludeId: 0,
    storeId: 0,
    initialSelected: null,
  },
);

const emit = defineEmits<{
  'update:modelValue': [value: number];
  change: [item: Record<string, any> | null];
}>();

const open = ref(false);
const loading = ref(false);
const keyword = ref('');
const options = ref<any[]>([]);
const selectedItem = ref<any>(null);
let searchTimer: ReturnType<typeof setTimeout> | undefined;

const displayName = computed(
  () => selectedItem.value?.nick_name || '请选择邀请人推广员',
);

async function fetchOptions(kw = '') {
  loading.value = true;
  try {
    const params: Record<string, any> = {
      keyword: kw.trim(),
      exclude_id: props.excludeId,
    };
    if (props.storeId > 0) {
      params.store_id = props.storeId;
    }
    options.value = (await salespersonOptionsApi(params)) ?? [];
    if (props.modelValue > 0 && !selectedItem.value) {
      selectedItem.value =
        options.value.find((o) => Number(o.id) === Number(props.modelValue)) ??
        selectedItem.value;
    }
  } finally {
    loading.value = false;
  }
}

function handleSearch() {
  if (searchTimer) clearTimeout(searchTimer);
  searchTimer = setTimeout(() => fetchOptions(keyword.value), 300);
}

function openDrawer() {
  open.value = true;
  keyword.value = '';
  fetchOptions('');
}

function pick(item: any) {
  selectedItem.value = item;
  emit('update:modelValue', Number(item.id));
  emit('change', item);
  open.value = false;
}

function clear() {
  selectedItem.value = null;
  emit('update:modelValue', 0);
  emit('change', null);
}

watch(
  () => props.modelValue,
  (val) => {
    if (val <= 0) {
      selectedItem.value = null;
    } else if (props.initialSelected && Number(props.initialSelected.id) === Number(val)) {
      selectedItem.value = props.initialSelected;
    }
  },
  { immediate: true },
);
</script>

<template>
  <div>
    <div
      class="flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 px-3 py-2 hover:border-blue-400"
      @click="openDrawer"
    >
      <Avatar v-if="selectedItem?.avatar" :src="selectedItem.avatar" :size="36" />
      <Avatar v-else :size="36">{{ (selectedItem?.nick_name || '?').charAt(0) }}</Avatar>
      <div class="min-w-0 flex-1">
        <div class="truncate font-medium">{{ displayName }}</div>
        <div v-if="selectedItem?.phone" class="text-xs text-gray-500">
          <SensitiveText :record="selectedItem" field="phone" :show-eye="false" />
        </div>
      </div>
      <a class="text-xs text-gray-400" @click.stop="clear">清空</a>
    </div>

    <Drawer v-model:open="open" title="选择邀请人推广员" width="420">
      <Input
        v-model:value="keyword"
        allow-clear
        class="mb-4"
        placeholder="搜索姓名、手机号"
        @change="handleSearch"
      />
      <Spin :spinning="loading">
        <Empty v-if="!loading && !options.length" description="无匹配推广员" />
        <div
          v-for="item in options"
          :key="item.id"
          class="mb-2 flex cursor-pointer items-center gap-3 rounded-lg border border-gray-100 px-3 py-3 hover:bg-gray-50"
          @click="pick(item)"
        >
          <Avatar v-if="item.avatar" :src="item.avatar" :size="40" />
          <Avatar v-else :size="40">{{ (item.nick_name || '?').charAt(0) }}</Avatar>
          <div>
            <div class="font-medium">{{ item.nick_name }}</div>
            <div class="text-xs text-gray-500">
              <SensitiveText :record="item" field="phone" :show-eye="false" />
            </div>
          </div>
        </div>
      </Spin>
    </Drawer>
  </div>
</template>
