<script lang="ts" setup>
/**
 * 总仓库新增：搜索尚未加入总仓（yii_drugstore_drug）的药品
 */
import { ref, watch, onMounted, onUnmounted } from 'vue';

import { SearchOutlined, LoadingOutlined } from '@ant-design/icons-vue';
import { Input, Spin } from 'ant-design-vue';
import { debounce } from 'lodash-es';

import { searchAvailableWarehouseDrugs } from '#/views/business/warehouse-drug-management/admin/api';

const TCM_PLACEHOLDER_IMAGE =
  'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250510/cd470ebf97e31c4048ba502ba71b66a3.jpg';

const PRODUCT_TYPE_LABEL: Record<number, string> = {
  1: '中药',
  2: '西药',
  3: '保健食品',
  4: '中成药',
  5: '产品服务包',
  6: '非药品',
  7: '医疗器械',
};

interface Props {
  productType?: number;
  placeholder?: string;
  disabled?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  productType: 1,
  placeholder: '',
  disabled: false,
});

const emit = defineEmits<{
  (e: 'select', drug: WarehouseDrugItem): void;
}>();

export interface WarehouseDrugItem {
  id: number;
  drug_name: string;
  pinyin_simple?: string;
  specification?: string;
  image?: string;
  type?: number;
  supplier?: { id?: number; name?: string };
}

const searchKeyword = ref('');
const isSearching = ref(false);
const searchResults = ref<WarehouseDrugItem[]>([]);
const showDropdown = ref(false);
const containerRef = ref<HTMLElement | null>(null);
const highlightIndex = ref(-1);

function defaultPlaceholder() {
  const label = PRODUCT_TYPE_LABEL[props.productType] ?? '药品';
  return `输入${label}名称或拼音搜索`;
}

function resolveDropdownImage(item: WarehouseDrugItem): string {
  if (item.image) return item.image;
  if (props.productType === 1) return TCM_PLACEHOLDER_IMAGE;
  return '';
}

const searchDrugs = debounce(async (keyword: string) => {
  if (!keyword || keyword.length < 1) {
    searchResults.value = [];
    showDropdown.value = false;
    return;
  }

  isSearching.value = true;
  showDropdown.value = true;

  try {
    const res = await searchAvailableWarehouseDrugs({
      name: keyword,
      type: props.productType,
    });
    searchResults.value = Array.isArray(res) ? res : [];
  } catch {
    searchResults.value = [];
  } finally {
    isSearching.value = false;
  }
}, 300);

function handleInput(e: Event) {
  const target = e.target as HTMLInputElement;
  searchKeyword.value = target.value;
  highlightIndex.value = -1;
  searchDrugs(target.value);
}

function handleFocus() {
  if (searchResults.value.length > 0) {
    showDropdown.value = true;
  }
}

function handleSelectDrug(drug: WarehouseDrugItem) {
  emit('select', drug);
  searchKeyword.value = '';
  searchResults.value = [];
  showDropdown.value = false;
  highlightIndex.value = -1;
}

function handleKeydown(e: KeyboardEvent) {
  if (!showDropdown.value || searchResults.value.length === 0) return;

  switch (e.key) {
    case 'ArrowDown':
      e.preventDefault();
      highlightIndex.value = Math.min(
        highlightIndex.value + 1,
        searchResults.value.length - 1,
      );
      break;
    case 'ArrowUp':
      e.preventDefault();
      highlightIndex.value = Math.max(highlightIndex.value - 1, 0);
      break;
    case 'Enter':
      e.preventDefault();
      if (highlightIndex.value >= 0) {
        handleSelectDrug(searchResults.value[highlightIndex.value]);
      }
      break;
    case 'Escape':
      showDropdown.value = false;
      highlightIndex.value = -1;
      break;
  }
}

function handleClickOutside(e: MouseEvent) {
  if (containerRef.value && !containerRef.value.contains(e.target as Node)) {
    showDropdown.value = false;
    highlightIndex.value = -1;
  }
}

onMounted(() => {
  document.addEventListener('click', handleClickOutside);
});

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
});

watch(
  () => props.productType,
  () => {
    searchResults.value = [];
    showDropdown.value = false;
    searchKeyword.value = '';
  },
);
</script>

<template>
  <div ref="containerRef" class="warehouse-drug-search">
    <Input
      v-model:value="searchKeyword"
      :placeholder="placeholder || defaultPlaceholder()"
      :disabled="disabled"
      allow-clear
      @input="handleInput"
      @focus="handleFocus"
      @keydown="handleKeydown"
    >
      <template #prefix>
        <LoadingOutlined v-if="isSearching" class="text-gray-400" />
        <SearchOutlined v-else class="text-gray-400" />
      </template>
    </Input>

    <div v-if="showDropdown" class="warehouse-drug-dropdown">
      <div v-if="isSearching" class="warehouse-drug-dropdown__loading">
        <Spin size="small" />
        <span>搜索中...</span>
      </div>
      <div
        v-else-if="searchResults.length === 0"
        class="warehouse-drug-dropdown__empty"
      >
        暂无匹配药品（或已在总仓库中）
      </div>
      <div v-else class="warehouse-drug-dropdown__list">
        <div
          v-for="(item, index) in searchResults"
          :key="item.id"
          class="warehouse-drug-item"
          :class="{ 'warehouse-drug-item--active': index === highlightIndex }"
          @click="handleSelectDrug(item)"
          @mouseenter="highlightIndex = index"
        >
          <div class="warehouse-drug-item__image">
            <img
              v-if="resolveDropdownImage(item)"
              :src="resolveDropdownImage(item)"
              alt=""
              class="warehouse-drug-item__img"
              @error="(e) => ((e.target as HTMLImageElement).style.display = 'none')"
            />
            <div v-else class="warehouse-drug-item__img-placeholder">无图</div>
          </div>
          <div class="warehouse-drug-item__info">
            <div class="warehouse-drug-item__name">{{ item.drug_name }}</div>
            <div class="warehouse-drug-item__meta">
              <span v-if="item.specification" class="warehouse-drug-item__spec">
                规格：{{ item.specification }}
              </span>
              <span v-if="item.supplier?.name" class="warehouse-drug-item__supplier">
                供应商：{{ item.supplier.name }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.warehouse-drug-search {
  position: relative;
  width: 100%;
}

.warehouse-drug-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1050;
  margin-top: 4px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow:
    0 6px 16px 0 rgba(0, 0, 0, 0.08),
    0 3px 6px -4px rgba(0, 0, 0, 0.12),
    0 9px 28px 8px rgba(0, 0, 0, 0.05);
  max-height: 400px;
  overflow: hidden;

  &__loading,
  &__empty {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px;
    color: #999;
    font-size: 14px;
  }

  &__list {
    max-height: 400px;
    overflow-y: auto;
    padding: 4px 0;
  }
}

.warehouse-drug-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background-color 0.2s;

  &:hover,
  &--active {
    background-color: #f5f7fa;
  }

  &__image {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
  }

  &__img {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid #f0f0f0;
  }

  &__img-placeholder {
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f5f5f5;
    border-radius: 6px;
    font-size: 12px;
    color: #bbb;
  }

  &__info {
    flex: 1;
    min-width: 0;
    overflow: hidden;
  }

  &__name {
    font-size: 14px;
    font-weight: 500;
    color: #333;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 4px;
  }

  &__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 12px;
    color: #999;
  }

  &__spec {
    color: #666;
  }

  &__supplier {
    color: #1890ff;
  }
}
</style>