<script setup lang="ts">
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
import { NInput, NButton, NIcon } from 'naive-ui'
import { Icon } from '@iconify/vue'
import { getPageTypeMeta } from '@/shared/api/common'
import { pageTypeToSlug } from '@/shared/utils/slug'
import axios from 'axios'
import { t } from '@/shared/i18n'

const props = defineProps<{ df: any; record: Record<string, any>; canEdit: boolean; ctx: any }>()

// Label布局
const labelLayout = computed(() => props.df.label_layout || 'vertical')

// 动态链接的目标 pagetype：从 df.options 指定的字段中读取
// 例如 df.options = "reference_pagetype"，则从 record["reference_pagetype"] 获取目标类型
const dynamicPagetype = computed(() => {
  const optionsField = props.df.options
  if (!optionsField) return ''
  return props.record[optionsField] || ''
})

const inputValue = ref('')
const displayValue = ref('')
const searchQuery = ref('')
const showButtons = ref(false)
const showDropdown = ref(false)
const dropdownOptions = ref<any[]>([])
const isLoading = ref(false)
const pageTypeConfig = ref<Record<string, any>>({})
const titleFieldCache = ref<Record<string, string>>({})

const hasValue = computed(() => !!inputValue.value)
const maxOptions = computed(() => props.df.max_options || 20)

// 同步 record 值 → inputValue
watch(() => props.record[props.df.fieldname], async (newValue) => {
  if (newValue !== inputValue.value) {
    inputValue.value = newValue || ''
    if (newValue && dynamicPagetype.value) {
      displayValue.value = await getRecordTitle(dynamicPagetype.value, newValue)
    } else {
      displayValue.value = ''
    }
  }
}, { immediate: true })

// 同步 inputValue → record
watch(inputValue, (newValue, oldValue) => {
  if (props.record[props.df.fieldname] !== newValue) {
    props.record[props.df.fieldname] = newValue
    if (props.ctx?.onFieldChange && newValue !== oldValue) {
      props.ctx.onFieldChange(props.df.fieldname, newValue, oldValue, props.record)
    }
  }
})

// 当目标 pagetype 变化时，清除当前值（类型变了，旧值无效）
watch(dynamicPagetype, (newType, oldType) => {
  if (newType !== oldType && inputValue.value) {
    inputValue.value = ''
    displayValue.value = ''
    searchQuery.value = ''
    showDropdown.value = false
  }
})

async function getPageTypeConfig(pagetype: string) {
  if (!pagetype) return {}
  if (pageTypeConfig.value[pagetype]) {
    return pageTypeConfig.value[pagetype]
  }
  try {
    const result = await getPageTypeMeta(pagetype)
    const config = result.success && result.data ? result.data : {}
    pageTypeConfig.value[pagetype] = config
    return config
  } catch (error) {
    return {}
  }
}

async function getRecordTitle(pagetype: string, recordName: string) {
  if (!pagetype || !recordName) return recordName
  const cacheKey = `${pagetype}_${recordName}`
  if (titleFieldCache.value[cacheKey]) {
    return titleFieldCache.value[cacheKey]
  }
  try {
    const config = await getPageTypeConfig(pagetype)
    const titleField = config.title_field || 'name'
    const showTitleFieldInLink = config.show_title_field_in_link || false

    if (titleField === 'name' || !showTitleFieldInLink) {
      const translated = t(recordName)
      titleFieldCache.value[cacheKey] = translated
      return translated
    }

    const response = await axios.get(`/api/data/${encodeURIComponent(pagetype)}/${encodeURIComponent(recordName)}`)
    const recordData = response.data?.data || {}
    const titleValue = recordData[titleField] || recordName
    const translated = t(titleValue)
    titleFieldCache.value[cacheKey] = translated
    return translated
  } catch (error) {
    return t(recordName)
  }
}

function createNewOption() {
  return {
    label: `${t('Create')}${t(dynamicPagetype.value)}`,
    value: 'create_new',
    type: 'create'
  }
}

async function searchOptions(query: string = '') {
  if (!dynamicPagetype.value) return

  isLoading.value = true
  try {
    const response = await axios.post('/api/action/jingrow.desk.search.search_link', {
      pagetype: dynamicPagetype.value,
      txt: query || '',
      page_length: maxOptions.value
    })

    if (response.data && response.data.message) {
      const results = response.data.message
      const processedRecords = results
        .filter((item: any) => item.value && item.value !== 'create_new__link_option' && item.value !== 'advanced_search__link_option')
        .map((item: any) => {
          const displayLabel = item.label || item.value
          return {
            label: t(displayLabel),
            value: item.value,
            title: t(displayLabel)
          }
        })
      dropdownOptions.value = [...processedRecords, createNewOption()]
    } else {
      dropdownOptions.value = [createNewOption()]
    }
  } catch (error) {
    dropdownOptions.value = [createNewOption()]
  } finally {
    isLoading.value = false
  }
}

function handleInputChange(value: string) {
  searchQuery.value = value
  if (showDropdown.value) {
    searchOptions(value)
  }
}

async function handleInputClick() {
  if (!props.canEdit) return
  if (!dynamicPagetype.value) return
  if (showDropdown.value) return

  await searchOptions(searchQuery.value)
  showDropdown.value = true
}

async function handleOptionSelect(option: any) {
  if (option.type === 'create') {
    const pagetypeSlug = pageTypeToSlug(dynamicPagetype.value)
    const randomStr = Math.random().toString(36).substring(2, 12)
    const tempName = `new-${pagetypeSlug}-${randomStr}`
    window.open(`/app/${pagetypeSlug}/${tempName}`, '_blank')
    showDropdown.value = false
    return
  }

  inputValue.value = option.value
  displayValue.value = option.title || option.label
  searchQuery.value = ''
  showDropdown.value = false
}

function clearValue() {
  inputValue.value = ''
  displayValue.value = ''
  searchQuery.value = ''
  showDropdown.value = false
}

function openLinkDetail() {
  if (!inputValue.value || !dynamicPagetype.value) return
  const pagetypeSlug = pageTypeToSlug(dynamicPagetype.value)
  window.open(`/app/${pagetypeSlug}/${inputValue.value}`, '_blank')
}

function showLinkButtons() {
  showButtons.value = hasValue.value
}

function hideLinkButtons() {
  showButtons.value = false
}

function handleClickOutside(event: Event) {
  const target = event.target as HTMLElement
  if (!target.closest('.link-field-container')) {
    showDropdown.value = false
  }
}

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

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
})
</script>

<template>
  <div :class="['field-wrapper', `layout-${labelLayout}`]">
    <label class="field-label">
      {{ ctx.t(df.label || df.fieldname) }}
      <span v-if="df.reqd" class="required">*</span>
    </label>

    <div class="link-field-container" @mouseenter="showLinkButtons" @mouseleave="hideLinkButtons">
      <div class="input-wrapper">
        <!-- 无目标 pagetype 时显示提示 -->
        <n-input
          v-if="!dynamicPagetype"
          :value="inputValue"
          :placeholder="t('Select a PageType first')"
          disabled
          class="link-input"
        />
        <!-- 有目标 pagetype 时显示 Link 搜索输入 -->
        <n-input
          v-else
          :value="hasValue ? displayValue : searchQuery"
          :placeholder="''"
          :disabled="!canEdit"
          @update:value="handleInputChange"
          @click="handleInputClick"
          @focus="handleInputClick"
          class="link-input"
        />

        <div v-if="showButtons && hasValue && dynamicPagetype" class="link-buttons">
          <n-button
            v-if="canEdit"
            size="small"
            quaternary
            @click.stop="clearValue"
            :title="t('Clear')"
            class="action-btn"
          >
            <template #icon>
              <n-icon><Icon icon="mdi:close" /></n-icon>
            </template>
          </n-button>

          <n-button
            size="small"
            quaternary
            @click.stop="openLinkDetail"
            :title="t('Open Detail')"
            class="action-btn"
          >
            <template #icon>
              <n-icon><Icon icon="mdi:arrow-right" /></n-icon>
            </template>
          </n-button>
        </div>
      </div>

      <!-- 下拉候选列表 -->
      <div v-if="showDropdown" class="dropdown-menu">
        <div class="dropdown-content">
          <div
            v-for="option in dropdownOptions"
            :key="option.value"
            class="dropdown-item"
            :class="{ 'create-item': option.type === 'create' }"
            @click="handleOptionSelect(option)"
          >
            <span v-if="option.type === 'create'" class="create-icon">
              <Icon icon="mdi:plus" />
            </span>
            <span class="item-label">{{ option.label }}</span>
          </div>

          <div v-if="dropdownOptions.length === 0 && !isLoading" class="empty-state">
            {{ t('No Data') }}
          </div>

          <div v-if="isLoading" class="loading-state">
            {{ t('Loading') }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.field-wrapper :deep(.link-field-container) {
  flex: 1;
  position: relative;
}

.link-field-container {
  position: relative;
}

.input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.link-input {
  flex: 1;
}

.link-buttons {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  background: white;
  padding: 2px;
  border-radius: 4px;
}

.action-btn {
  width: 24px;
  height: 24px;
  min-width: 24px;
  padding: 0;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1000;
  margin-top: 4px;
}

.dropdown-content {
  background: white;
  border: 1px solid #e0e0e6;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  max-height: 200px;
  overflow-y: auto !important;
}

.dropdown-item {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.dropdown-item:last-child {
  border-bottom: none;
}

.dropdown-item:hover {
  background-color: #f5f5f5;
}

.create-item {
  color: #18a058;
  font-weight: 500;
}

.create-icon {
  color: #18a058;
}

.item-label {
  flex: 1;
}

.empty-state,
.loading-state {
  padding: 12px;
  text-align: center;
  color: #999;
  font-size: 14px;
}

.field-wrapper :deep(.n-input) {
  flex: 1;
}
</style>

