<script setup lang="ts">
import { ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import axiosClient from '@/services/HttpService'
import mime from 'mime'

import type { StorageFile } from '@/stores/storage'
import { useSearchDataStore } from '@/stores/searched-data'
import { useLoader } from '@/stores/loader'
import { useFileInfoStore } from '@/stores/file-info-data'

import AdvancedSearch from '@/modules/01_user/components/AdvancedSearch.vue'
import useStorage from '@/stores/storage'

interface SearchInfo {
  field: string
  value: string
  exact?: boolean
}
interface SearchOperator {
  AND?: (SearchInfo | SearchOperator)[]
  OR?: (SearchInfo | SearchOperator)[]
}
interface Search extends SearchOperator {
  recursive?: boolean
  path?: string[]
  exact?: boolean
}

const loaderStore = useLoader()
const storageStore = useStorage()
const { currentInfo } = storeToRefs(storageStore)
const { isFilePreview } = storeToRefs(useFileInfoStore())
const {
  isExact,
  isSearch,
  isAdvSearchCall,
  searchData,
  advSearchDataField,
  optionsField,
  advSearchDataRow,
} = storeToRefs(useSearchDataStore())
const { getFoundFile } = useSearchDataStore()

const submitSearchData = ref<Search>({
  AND: [],
  OR: [],
})

const props = defineProps<{
  mode: 'admin' | 'user'
}>()

async function submitSearch() {
  isFilePreview.value = false
  if (searchData.value.value.trim() !== '') {
    submitSearchData.value = { AND: [], OR: [] }
    if (props.mode === 'admin') {
      submitSearchData.value.exact = true
      submitSearchData.value.recursive = true
      submitSearchData.value.path = currentInfo.value.path
        .split('/')
        .filter(Boolean)

      optionsField.value.forEach((option) => {
        submitSearchData.value.OR?.push({
          field: option.value,
          value: searchData.value.value,
        })
      })
      submitSearchData.value.OR?.push({
        field: 'fileName',
        value: searchData.value.value,
      })
      submitSearchData.value.OR?.push({
        field: 'metadata.author',
        value: searchData.value.value,
      })
      submitSearchData.value.OR?.push({
        field: 'metadata.subject',
        value: searchData.value.value,
      })
      submitSearchData.value.OR?.push({
        field: 'fileType',
        value: mime.getType(searchData.value.value) || '',
      })
    } else {
      submitSearchData.value.recursive = true
      submitSearchData.value.path = []
      if (searchData.value.field == 'title') {
        submitSearchData.value.OR?.push({
          field: 'metadata.subject',
          value: searchData.value.value,
        })
      }
      if (searchData.value.field == 'author') {
        submitSearchData.value.OR?.push({
          field: 'metadata.author',
          value: searchData.value.value,
        })
      }
      submitSearchData.value.OR?.push({
        field: searchData.value.field,
        value: searchData.value.value,
        exact: isExact.value,
      })
      if (isAdvSearchCall.value) {
        let advField = advSearchDataField.value
        let advRow = advSearchDataRow.value

        advRow.forEach(
          (d: { field: string; value: string; op: string; exact: boolean }) => {
            if (d.field && d.value.trim() !== '') {
              const op = d.op === 'AND' ? 'AND' : 'OR'
              if (
                (op === 'AND' && d.field === 'title') ||
                d.field === 'author'
              ) {
                console.log('and title author')
                if (d.field === 'title') {
                  submitSearchData.value[op]?.push({
                    OR: [
                      {
                        field: d.field,
                        value: d.value,
                        exact: d.exact,
                      },
                      {
                        field: 'metadata.subject',
                        value: d.value,
                        exact: d.exact,
                      },
                    ],
                  })
                }
                if (d.field === 'author') {
                  submitSearchData.value[op]?.push({
                    OR: [
                      {
                        field: d.field,
                        value: d.value,
                        exact: d.exact,
                      },
                      {
                        field: 'metadata.author',
                        value: d.value,
                        exact: d.exact,
                      },
                    ],
                  })
                }
              } else {
                submitSearchData.value[op]?.push({
                  field: d.field,
                  value: d.value,
                  exact: d.exact,
                })
              }
            }
          },
        )
        if (advField.keyword.length > 0) {
          for (let i = 0; i < advField.keyword.length; i++) {
            submitSearchData.value.AND?.push({
              field: 'keyword',
              value: advField.keyword[i],
              exact: true,
            })
          }
        }
        if (advField.description.trim() !== '') {
          submitSearchData.value.AND?.push({
            field: 'description',
            value: advField.description,
            exact: true,
          })
        }
      }
    }

    try {
      loaderStore.show()
      const res = await axiosClient.post<StorageFile[]>(
        `${import.meta.env.VITE_API_ENDPOINT}/search`,
        submitSearchData.value,
      )
      getFoundFile(res.data)
      isSearch.value = true
    } catch (error) {
      console.error('Error during the request', error)
    } finally {
      loaderStore.hide()
    }
  }
}

watch(
  () => searchData.value.value,
  (search) => {
    if (search.length === 0) {
      isSearch.value = false
    }
  },
)
</script>

<template>
  <div class="col-3" v-if="mode === 'admin'">
    <q-input
      rounded
      outlined
      dense
      label="ค้นหา"
      debounce="300"
      bg-color="white"
      v-model="searchData.value"
      id="inputSearch"
      @update:model-value="submitSearch"
      @keydown.enter.prevent="submitSearch"
      data-testid="searchAdmin"
    >
      <template v-slot:prepend />
      <template v-slot:append
        ><q-icon name="search" class="pointer" @click="submitSearch"
      /></template>
    </q-input>
  </div>

  <div v-if="mode === 'user'">
    <div class="q-pa-md bg-grey-1">
      <div class="row items-center q-col-gutter-md">
        <div class="col-12 col-md-3">
          <q-select
            id="searchField"
            dense
            outlined
            emit-value
            map-options
            class="bg-white"
            v-model="searchData.field"
            :options="optionsField"
          />
        </div>
        <div class="col-12 col-md-grow">
          <q-input
            id="searchValue"
            class="bg-white"
            dense
            outlined
            v-model="searchData.value"
            placeholder="เอกสาร"
            @keydown.enter.prevent="submitSearch"
          >
            <template v-slot:append>
              <q-icon
                v-if="searchData.value"
                name="close"
                @click="() => ((searchData.value = ''), (isSearch = false))"
                class="cursor-pointer"
                id="clearSearchData"
              />
            </template>
          </q-input>
        </div>
        <div>
          <q-checkbox
            id="specificBox"
            v-model="isExact"
            label="ค้นหาตรงตัว"
            color="grey"
            keep-color
          />
        </div>
      </div>

      <div class="col">
        <div class="row items-center justify-between q-gutter-y-md q-pt-sm">
          <div class="col-grow">
            <advanced-search :submitSearch="submitSearch" />
          </div>
          <div v-if="isAdvSearchCall === false">
            <q-btn
              style="width: 150px"
              color="primary"
              label="ค้นหา"
              class="q-mt-sm"
              icon="mdi-magnify"
              @click="submitSearch"
              id="submitSearch"
            />
          </div>
        </div>
      </div>
    </div>
    <q-separator />
  </div>
</template>

<style scoped>
.pointer {
  cursor: pointer;
}
</style>
