<script setup lang="ts">
import { onUnmounted, ref, computed, type Ref, onMounted, reactive, h, watch } from "vue";
import { useRoute } from "vue-router";
import { LoadingOutlined } from '@ant-design/icons-vue';
import { useSideBarStore } from "@/stores/side-bar";
import SearchBox from "./components/SearchBox.vue";
import SearchResultToolbar from "./components/SearchResultToolbar.vue";
import SearchResultList from "./components/SearchResultList.vue";
import type { SearchRequest } from "@/types/request.types";
import { useSearchStore } from "@/stores/search.store";
import { routeToSearch } from "@/router";
import AdvancedSearchBox from "./components/AdvancedSearchBox.vue";
import type { SearchRouteParam } from "@/types/route.type";
import type { ResultMode, Sort } from "@/types/search.types";
import FilterCard from "./components/FilterCard.vue";
import { CompLog } from "@/libs/log.lib";

const logError = CompLog.logErr("SearchResultView")

const sideBarStore = useSideBarStore();

const searchStore = useSearchStore();

// 当前路由对象
const route = useRoute();

// 关键词
const keyword = ref("");
// 字段
const field = ref("TP");
// 排序
const sort: Ref<Sort> = ref("Relevance");
const placeholder = ref("请输入文献主题") 

const pagination = reactive({
  page: 1,
  size: 10,
})

const authorChecked: Ref<string[]> = ref([]);
const yearChecked: Ref<string[]> = ref([]);
const unitChecked = ref<string[]>();

const searchResult = computed(() => searchStore.result);
const yearAggResult = computed(() => searchStore.yearAggResult);
const authorAggResult = computed(() => searchStore.authorAggResult);
const unitAggResult = computed(() => searchStore.unitAggResult);

const searchType: Ref<'simple' | 'advanced'> = ref('simple');

const resultMode: Ref<ResultMode> = ref('detail');

const query = ref('');

// 加载状态
const spinning = ref(true);

interface SearchParams {
  query: string;
  yearSelected?: string[];
  authorSelected?: string[];
  unitSelected?: string[];
  sort?: Sort;
  page?: number;
  size?: number;
}

/**
 * 根据搜索状态数据执行搜索
 * @param searchParams 搜索状态数据
 */
function performSearch(searchParams: SearchParams) {
  spinning.value = true;
  let sortParam: Object = { "Relevance": "Relevance" };
  if (searchParams.sort) {
    const sort = searchParams.sort;
    if (sort === 'DateDesc') {
      sortParam = { "year": "DESC" }
    } else if (sort === 'DateAsc') {
      sortParam = { "year": "ASC" }
    } else if (sort === 'CitedDesc') {
      sortParam = { "cited": "DESC" }
    }
  }

  let filters: string[] = []
  if (searchParams.yearSelected && searchParams.yearSelected.length > 0) {
    filters.push(`PY=(${searchParams.yearSelected.join(" ")})`);
  }
  if (searchParams.authorSelected && searchParams.authorSelected.length > 0) {
    filters.push(`AU=(${searchParams.authorSelected.join(" OR ")})`);
  }
  if (searchParams.unitSelected && searchParams.unitSelected.length > 0) {
    filters.push(`UN=(${searchParams.unitSelected.join(" OR ")})`)
  }
  const filter = filters.join(" AND ");

  // size
  const size = Math.max(searchParams.size || 10, 10);
  // from
  const from = (Math.max(searchParams.page || 1, 1) - 1) * size;

  const commonParams = {
    query: searchParams.query,
    filter,
  }

  const param: SearchRequest = {
    ...commonParams,
    from,
    size,
    sort: sortParam,
    isSaveHis: true,
  };

  searchStore.search(param)
    .then(() => spinning.value = false)
    .catch((err) => {
      spinning.value = false
      logError(err)
    });
  searchStore.aggYear(commonParams);
  searchStore.aggAuthor(commonParams);
  searchStore.aggUnit(commonParams);
}

/**
 * 执行搜索，同时修改url
 */
function doSearch() {
  let params: SearchRouteParam = {
    type: searchType.value,
  }
  if (searchType.value == 'simple') {
    params['field'] = field.value;
    params['kw'] = keyword.value;
  } else {
    params['query'] = query.value;
  }

  const extras = {
    page: pagination.page,
    size: pagination.size,
    yearSelected: yearChecked.value,
    authorSelected: authorChecked.value,
    unitSelected: unitChecked.value,
    sort: sort.value,
  }
  routeToSearch(params, extras);

  const searchParams: SearchParams = {
    query: query.value,
    yearSelected: yearChecked.value,
    authorSelected: authorChecked.value,
    unitSelected: unitChecked.value,
    page: pagination.page,
    size: pagination.size,
    sort: sort.value,
  };
  performSearch(searchParams);
}

function onSimpleSearch() {
  routeToSearch({type: 'simple', field: field.value, kw: keyword.value});
  doSearch();
}

function onAdvancedSearch() {
  routeToSearch({ type: 'advanced', query: query.value })
  doSearch();
}

/**
 * 根据url包含的信息，初始化状态信息
 */
function setupState() {
  const queryParam = route.query;
  if (queryParam.type == 'advanced') {
    searchType.value = 'advanced';
    query.value = queryParam.query as string;
  } else {
    searchType.value = 'simple';
    // 初始化关键词
    if (route.query.kw) {
      keyword.value = (route.query.kw as string).trim();
    }
    if (route.query.field) {
      field.value = (route.query.field as string).trim();
    }
    query.value = `${field.value}=(${keyword.value})`
  }

  if (queryParam.yearSelected) {
    let yearSelected: string[];
    if (Array.isArray(queryParam.yearSelected)) {
      yearSelected = queryParam.yearSelected as string[];
    } else {
      yearSelected = [queryParam.yearSelected];
    }
    yearChecked.value = yearSelected;
  }

  if (queryParam.authorSelected) {
    let authorSelected: string[];
    if (Array.isArray(queryParam.authorSelected)) {
      authorSelected = queryParam.authorSelected as string[];
    } else {
      authorSelected = [queryParam.authorSelected];
    }
    authorChecked.value = authorSelected;
  }
  if (queryParam.sort) {
    sort.value = queryParam.sort as Sort;
  }
  if (queryParam.page) {
    pagination.page = parseInt(queryParam.page as string);
  }
  if (queryParam.size) {
    pagination.size = parseInt(queryParam.size as string);
  }
}

onMounted(() => {
  // 收起左侧边栏
  sideBarStore.setCollapse(true);
  // 初始化状态
  setupState();
  // 搜索
  doSearch();
});

function changeField(value: string) {
  field.value = value;
  query.value = `${field.value}=(${keyword.value})`;
}

function changKeyword(value: string) {
  keyword.value = value;
  query.value = `${field.value}=(${keyword.value})`;
}

function changeSort(val: any) {
  sort.value = val;
  doSearch();
}

function onPaginationChange(page: any, pageSize: any) {
  pagination.page = page;
  pagination.size = pageSize;
  doSearch();
}

function onModeChange(mode: ResultMode) {
  resultMode.value = mode;
}

function onYearFilterChange(selected: string[]) {
  pagination.page = 1;
  yearChecked.value = selected
  doSearch();
}

function onAuthorFilterChange(selected: string[]) {
  pagination.page = 1;
  authorChecked.value = selected
  doSearch();
}

function onUnitFilterChange(selected: string[]) {
  pagination.page = 1;
  unitChecked.value = selected
  doSearch()
}

watch(field, (newValue) => {
  if (newValue == 'TI') {
    placeholder.value = "请输入文献标题"
  } else if (newValue == 'AU') {
    placeholder.value = "请输入文献作者"
  } else if (newValue == 'KW') {
    placeholder.value = "请输入文献关键词"
  } else if (newValue == 'AB') {
    placeholder.value = "请输入文献摘要"
  } else if (newValue == 'UN') {
    placeholder.value = "请输入文献机构"
  } else {
    placeholder.value = "请输入文献主题"
  }
});

onUnmounted(() => {
  sideBarStore.setCollapse(false);
});
</script>

<template>
  <div class="search-result-wrap">
    <div class="search-box-wrap" v-if="searchType == 'simple'">
      <SearchBox
        v-model:keyword="keyword"
        v-model:field="field"
        :placeholder="placeholder"
        @search="onSimpleSearch"
        @update:field="changeField"
        @update:keyword="changKeyword"
      />
    </div>
    <div class="search-box-wrap" v-if="searchType == 'advanced'">
      <AdvancedSearchBox v-model:query="query" @search="onAdvancedSearch" />
    </div>
    <a-row type="flex" class="search-result-main" :gutter="10">
      <a-col :span="5">
        <div class="left-filter-header">
          筛选
        </div>
        <a-space direction="vertical" style="width: 100%" v-if="searchResult">
          <FilterCard
            v-if="yearAggResult"
            title="时间"
            :aggs="yearAggResult"
            :checked="yearChecked"
            @change="onYearFilterChange"
          />
          <FilterCard
            v-if="authorAggResult"
            title="作者"
            :aggs="authorAggResult"
            :checked="authorChecked"
            @change="onAuthorFilterChange"
          />
          <FilterCard
            v-if="unitAggResult"
            title="机构"
            :aggs="unitAggResult"
            :checked="unitChecked"
            @change="onUnitFilterChange"
          />
        </a-space>
      </a-col>
      <a-col :span="19">
        <a-spin :spinning="spinning" :indicator="h(LoadingOutlined, { style: { fontSize: '24px', }, spin: true, })">
          <SearchResultToolbar
            v-if="searchResult"
            :data="searchResult"
            v-model:sort="sort"
            v-model:pagination="pagination"
            @update:sort="changeSort"
            @paginationChange="onPaginationChange"
            @modeChange="onModeChange"
          />
          <SearchResultList :data="searchResult" :mode="resultMode" v-if="searchResult" />
        </a-spin>
      </a-col>
    </a-row>
  </div>
</template>

<style scoped lang="scss">
.search-result-wrap {
  margin-top: 20px;
  .search-box-wrap {
    padding: 0 120px;
  }

  .search-result-main {
    margin-top: 20px;
    :deep em {
      color: red;
      font-style: normal;
    }
  }

  @media (max-width: 1024px) {
    .search-box-wrap {
      padding: 0 20px;
    }
  }
}
</style>
