<script lang="ts" setup>
import type { ColumnType, TableType } from 'nocodb-sdk'
import { UITypes, isSystemColumn } from 'nocodb-sdk'

const reloadData = inject(ReloadViewDataHookInj)!

const { meta } = useSmartsheetStoreOrThrow()

const activeView = inject(ActiveViewInj, ref())

const { search, loadFieldQuery } = useFieldQuery()

const isDropdownOpen = ref(false)

const showSearchBox = ref(false)

const globalSearchRef = ref<HTMLInputElement>()

const globalSearchWrapperRef = ref<HTMLInputElement>()

const { isMobileMode } = useGlobal()

const columns = computed(
  () => (meta.value as TableType)?.columns?.filter((column) => !isSystemColumn(column) && column?.uidt !== UITypes.Links) ?? [],
)

watch(
  () => activeView.value?.id,
  (n, o) => {
    if (n !== o) {
      loadFieldQuery(activeView.value?.id)
    }
  },
  { immediate: true },
)

function onPressEnter() {
  reloadData.trigger({ shouldShowLoading: false, offset: 0 })
}

const displayColumnLabel = computed(() => {
  if (search.value.field) {
    // use search field label if specified
    return columns.value?.find((column) => column.id === search.value.field)?.title
  }
  // use primary value label by default
  const pvColumn = columns.value?.find((column) => column.pv)
  search.value.field = pvColumn?.id as string
  return pvColumn?.title
})

watchDebounced(
  () => search.value.query,
  () => {
    onPressEnter()
  },
  {
    debounce: 500,
    maxWait: 600,
  },
)

const onSelectOption = (column: ColumnType) => {
  search.value.field = column.id as string
  isDropdownOpen.value = false
}

const handleShowSearchInput = () => {
  showSearchBox.value = true

  nextTick(() => {
    globalSearchRef.value?.focus()
  })
}

onClickOutside(globalSearchWrapperRef, (e) => {
  const targetEl = e.target as HTMLElement
  if (search.value.query || targetEl.closest('.nc-dropdown-toolbar-search-field-option')) {
    return
  }

  showSearchBox.value = false
})
</script>

<template>
  <div ref="globalSearchWrapperRef" class="nc-global-search-wrapper">
    <a-button
      v-if="!search.query && !showSearchBox"
      class="nc-toolbar-btn"
      data-testid="nc-global-search-show-input"
      @click="handleShowSearchInput"
    >
      <GeneralIcon icon="search" class="h-4 w-4 text-gray-700 group-hover:text-black" />
    </a-button>
    <div
      v-else
      class="flex flex-row border-1 rounded-lg h-7 xs:(h-10 ml-0) ml-1 border-gray-200 overflow-hidden focus-within:border-primary"
      :class="{ 'border-primary': search.query.length !== 0 }"
    >
      <NcDropdown
        v-model:visible="isDropdownOpen"
        :trigger="['click']"
        overlay-class-name="nc-dropdown-toolbar-search-field-option"
      >
        <div
          class="flex items-center group px-2 cursor-pointer border-r-1 border-gray-200 hover:bg-gray-100"
          :class="{ 'bg-gray-50 ': isDropdownOpen }"
          @click="isDropdownOpen = !isDropdownOpen"
        >
          <GeneralIcon icon="search" class="ml-1 mr-2 h-3.5 w-3.5 text-gray-500 group-hover:text-black" />
          <div v-if="!isMobileMode" class="w-16 text-xs font-medium text-gray-400 truncate">
            {{ displayColumnLabel }}
          </div>
          <div class="xs:(text-gray-600) group-hover:text-gray-700 sm:(text-gray-400)">
            <component :is="iconMap.arrowDown" class="text-sm text-inherit" />
          </div>
        </div>
        <template #overlay>
          <SmartsheetToolbarFieldListWithSearch
            :is-parent-open="isDropdownOpen"
            :selected-option-id="search.field"
            show-selected-option
            :options="columns"
            toolbar-menu="globalSearch"
            @selected="onSelectOption"
          />
        </template>
      </NcDropdown>

      <form class="p-0">
        <a-input
          v-if="search.query || showSearchBox"
          ref="globalSearchRef"
          v-model:value="search.query"
          name="globalSearchQuery"
          size="small"
          class="text-xs w-40 h-full"
          :placeholder="`${$t('general.searchIn')} ${displayColumnLabel}`"
          :bordered="false"
          data-testid="search-data-input"
          @press-enter="onPressEnter"
        >
        </a-input>
      </form>
    </div>
  </div>
</template>

<style scoped>
:deep(input::placeholder) {
  @apply !text-gray-400;
  line-height: 0.8rem !important;
  font-size: 0.8rem !important;
}
</style>
