<template>
  <!-- 通用列表页 -->
  <FlexCol 
    :padding="30"
    :backgroundColor="hasBg ? 'background.page' : ''"
  >
    <Tabs
      v-if="tabs"
      :tabs="tabs" 
      :width="700"
      v-model:currentIndex="tabCurrentIndex"
      :autoScroll="false"
      @click="handleTabClick"
    />
    <!-- 搜索 -->
    <SearchBar
      v-if="showSearch"
      v-model="searchValue"
      :placeholder="`输入关键词搜索${title}`" 
      @search="doSearch"
      @cancel="doSearch"
    />
    <!-- 下拉框 -->
    <FlexRow
      v-if="dropDownNames.length > 0" 
      :justify="dropDownVisibleCount >= 3 ? 'space-around' : 'space-between'"
      align="center"
    >
      <template v-for="(drop, k) in dropDownNames" :key="k" >
        <SimpleDropDownPicker 
          v-if="!drop.activeTab || drop.activeTab.includes(tabCurrentIndex)"
          :modelValue="dropDownValues[k]"
          :columns="drop.options"
          :style="{maxWidth: `${100/dropDownNames.length}%`}"
          @update:modelValue="(v) => handleChangeDropDownValue(k, v)"
        />
      </template>
      <FlexRow v-if="(showTotal && dropDownVisibleCount < 3)" center>
        <Text bold color="primary" :text="`总共有 ${ listLoader.total.value } 个`" />
      </FlexRow>
    </FlexRow>
    <FlexRow v-if="(dropDownVisibleCount >= 3 || dropDownVisibleCount == 0 && showTotal)" center :padding="20">
      <Text bold color="primary" :text="`总共有 ${ listLoader.total.value } 个`" />
    </FlexRow>
    
    <!-- 列表 -->
    <FlexRow 
      position="relative"
      wrap justify="space-between" align="stretch"
    >
      <FlexCol
        v-for="(item, i) in listLoader.list.value"
        :key="item.id"
        :flexGrow="1"
        :width="itemType.endsWith('-2') ? '50%' : '100%'"
      >
        <Box2LineLargeImageUserShadow 
          v-if="itemType.startsWith('image-large')"
          :width="100"
          titleColor="black"
          :classNames="getItemClass(i)"
          :image="getImage(item)"
          :titleBox="item.titleBox"
          :title="item.title"
          :desc="item.desc"
          :tags="item.bottomTags"
          :badge="item.badge"
          @click="goDetails(item, item.id)"
        />
        <Box2LineImageRightShadow 
          v-else-if="itemType.startsWith('article-common')"
          :width="100"
          titleColor="black"
          :titleBox="item.titleBox"
          :classNames="getItemClass(i)"
          :image="getImage(item)"
          :title="item.title"
          :desc="item.desc"
          :tags="item.bottomTags"
          :badge="item.badge"
          :wideImage="true"
          @click="goDetails(item, item.id)"
        />
        <Box2LineImageRightShadow 
          v-else-if="itemType.startsWith('article-character')"
          :width="100"
          :classNames="getItemClass(i)"
          :image="getImage(item)"
          titleColor="black"
          :title="item.title"
          :titleBox="item.titleBox"
          :tags="item.bottomTags || item.keywords"
          :desc="item.desc"
          :badge="item.badge"
          @click="goDetails(item, item.id)"
        />

      </FlexCol>
      <view v-if="itemType.endsWith('-2') && listLoader.list.value.length % 2 != 0" style="width:50%;" />
    </FlexRow>
    <SimplePageListLoader :loader="listLoader" />
  </FlexCol>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch, type PropType } from 'vue';
import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
import { navTo } from '@/components/utils/PageAction';
import SimplePageListLoader from '@/components/loader/SimplePageListLoader.vue';
import Box2LineLargeImageUserShadow from '@/common/components/parts/Box2LineLargeImageUserShadow.vue';
import Box2LineImageRightShadow from '@/common/components/parts/Box2LineImageRightShadow.vue';
import SimpleDropDownPicker, { type SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
import AppCofig from '@/common/config/AppCofig';
import Tabs from '@/components/nav/Tabs.vue';
import SearchBar from '@/components/form/SearchBar.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import FlexRow from '@/components/layout/FlexRow.vue';
import Text from '@/components/basic/Text.vue';

function getImage(item: any) {
  return item.thumbnail || item.image || AppCofig.defaultImage
}
function getItemClass(index: number) {
  return props.itemType.endsWith('-2') ? (index % 2 != 0 ? 'ml-1' : 'mr-1') : ''
}

export interface DropDownNames {
  options: SimpleDropDownPickerItem[],
  defaultSelectedValue: number|string,
  activeTab?: number[],
}
export interface CommonListItem extends Record<string, any>  {
  id: number,
  image: string,
  title: string,
}

const props = defineProps({
  /** 
   * 标题
   */
  title: {
    type: String,
    default: '',
  },
  /**
   * 分组标签
   */
  tabs: {
    type: Array as PropType<{ 
      id: number, 
      text: string,
      jump?: () => void,
    }[]>,
    default: null,
  },
  tabsScrollable: {
    type: Boolean,
    default: false, 
  },
  /**
   * 是否显示搜索框
   */
  showSearch: {
    type: Boolean,
    default: true,
  },
  /**
   * 初始搜索文本
   */
  intitalSearch: {
    type: String,
    default: '',
  },
  /**
   * 显示总数
   */
  showTotal: {
    type: Boolean,
    default: false,
  },
  /**
   * 下拉框选项控制
   */
  dropDownNames: {
    type: Object as PropType<DropDownNames[]>,
    default: () => ([]),
  },
  /**
   * 列表项类型
   */
  itemType: {
    type: String as PropType<'image-large-2'|'image-large'|'article-common'|'article-character'>,
    default: 'article-common',
  },
  /**
   * 分页大小
   */
  pageSize: {
    type: Number,
    default: 8,
  },
  /**
   * 加载数据函数
   * @param page 页码，从1开始
   * @param pageSize 分页大小
   * @param searchText 搜索文本
   * @param dropDownValues 下拉框值
   */
  load: {
    type: Function as PropType<(
      page: number, 
      pageSize: number,
      searchText: string,
      dropDownValues: number[],
      tabSelect: number,
    ) => Promise<{ list: CommonListItem[], total: number }>>,
    required: true,
  },
  /**
   * 点击详情跳转页面路径
   */
  detailsPage: {
    type: [String,Object],
    default: '/pages/article/details'
  },
  /**
   * 详情跳转页面参数
   */
  detailsParams: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({})
  },
  hasBg: {
    type: Boolean,
    default: true,
  },
  startTabIndex: {
    type: Number,
    default: undefined, 
  },
  loadMounted: {
    type: Boolean,
    default: true,
  },
})

const emit = defineEmits([ 'goCustomDetails' ])

const dropDownVisibleCount = computed(() => {
  let c = 0;
  for (const element of props.dropDownNames) {
    if (!element.activeTab || element.activeTab.includes(tabCurrentIndex.value))
      c++;
  }
  return c;
})
const dropDownValues = ref<any>([]);
const searchValue = ref(props.intitalSearch);
const listLoader = useSimplePageListLoader(props.pageSize, async (page, pageSize) => {
  return await props.load(
    page, pageSize, 
    searchValue.value,
    dropDownValues.value,
    props.tabs?.[tabCurrentIndex.value]?.id ?? tabCurrentIndex.value,
  )
});
const tabCurrentIndex = ref(0)

watch(() => props.intitalSearch, (newValue) => {
  searchValue.value = newValue;
});

function handleChangeDropDownValue(index: number, value: number) {
  dropDownValues.value[index] = value;
  listLoader.reload();
}
function handleTabClick(e: any) {
  nextTick(() => {
    if (props.tabs?.[tabCurrentIndex.value]?.jump) {
      props.tabs[tabCurrentIndex.value].jump?.();
      return;
    }
    listLoader.reload();
  })
}
function doSearch() {
  listLoader.reload();
}
function goDetails(item: any, id: number) {
  if (props.detailsPage == 'custom') {
    emit('goCustomDetails', item, id)
    return;
  }
  if (typeof props.detailsPage === 'object' && typeof props.detailsPage[0] === 'string') {
    navTo(props.detailsPage[tabCurrentIndex.value], { 
      ...props.detailsParams, 
      id 
    })
    return; 
  }
  if (typeof props.detailsPage == 'object' && typeof props.detailsPage[0] === 'object') {
    const item = props.detailsPage[tabCurrentIndex.value];
    navTo(item.page, { 
      ...item.params, 
      id 
    })
    return; 
  }
  navTo(props.detailsPage as string, { 
    ...props.detailsParams,
    id
  })
}

function loadDropDownValues() {
  dropDownValues.value = [];
  for (const element of props.dropDownNames) {
    dropDownValues.value.push(element.defaultSelectedValue);
  }
}

watch(tabCurrentIndex, () => {
  listLoader.reload();
});
watch(() => props.startTabIndex, () => {
  if (props.startTabIndex) {
    tabCurrentIndex.value = props.startTabIndex;
  }
});
watch(() => props.dropDownNames.length, () => {
  loadDropDownValues();
  listLoader.reload();
});

defineExpose({
  load: () => {
    listLoader.reload();
  },
})

onMounted(() => {
  if (props.startTabIndex)
    tabCurrentIndex.value = props.startTabIndex;
  if (props.title)
    uni.setNavigationBarTitle({ title: props.title, })
  loadDropDownValues();
  if (props.loadMounted)
    listLoader.reload();
});
</script>