<template>
  <CommonListPage
    v-if="currentCommonCategoryDefine && !loading"
    :startTabIndex="pageStartTab"
    :hasPadding="hasPadding"
    :hasBg="hasBg"
    v-bind="currentCommonCategoryContentDefine.props as any || undefined"
    :title="currentCommonCategoryDefine.title || undefined"
    :load="loadData"
    :tabs="tabs"
    :itemType="itemType"
    :dropDownNames="dropdownNames"
    :showListTabIds="showListTabIds"
    :detailsPage="detailsPage"
    :detailsParams="detailsParams"
  >
    <template #list="{ tabId }">
      <CommonCategoryBlocks
        v-if="tabRenderDefines[tabId]?.type === 'nestCategory'" 
        :categoryDefine="tabRenderDefines[tabId].categoryDefine"
        :parentData="currentParentData"
      />
      <CommonCategoryBlocks
        v-else-if="tabRenderDefines[tabId]?.type === 'list' && tabRenderDefines[tabId].preInsertCategorys?.length" 
        :categoryDefine="tabRenderDefines[tabId].categoryDefine"
        :parentData="currentParentData"
      />
    </template>
  </CommonListPage>
  <LoadingPage v-else />
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { navTo } from '@/components/utils/PageAction';
import { doGetDynamicListDataParams, doLoadDynamicCategoryDataMergeTypeGetColumns, doLoadDynamicDropdownData, doLoadDynamicListData } from './CommonCategoryDynamicData';
import { type IHomeCommonCategoryDefine, type IHomeCommonCategoryListDefine, type IHomeCommonCategoryListTabDefine, type IHomeCommonCategoryListTabNestCategoryItemDefine } from './CommonCategoryDefine';
import { resolveCommonContentSolveProps } from '../common/CommonContent';
import { waitTimeOut } from '@imengyu/imengyu-utils';
import type { SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
import type { CommonListPageProps, DropDownNames } from '../common/CommonListPage.vue';
import type { CategoryDefine } from './CommonCategoryBlocks';
import CommonListPage from '../common/CommonListPage.vue';
import CommonCategoryBlocks from './CommonCategoryBlocks.vue';
import LoadingPage from '@/components/display/loading/LoadingPage.vue';

/**
 * 动态通用内容 - 通用列表页
 */

const props = withDefaults(defineProps<{
  currentCommonCategoryDefine: IHomeCommonCategoryDefine['page'][0],
  currentCommonCategoryContentDefine: IHomeCommonCategoryListDefine,
  pageStartTab?: number,
  pageQuerys?: Record<string, any>,
  parentData?: any,
  hasPadding?: boolean,
  hasBg?: boolean,
}>(), {
  pageStartTab: 0,
  pageQuerys: () => ({}),
  hasPadding: true,
  hasBg: true,
});
const emit = defineEmits<{
  (e: 'error', error: any): void;
}>();

const loading = ref(false);

async function loadPageConfig() {
  loading.value = true;
  await waitTimeOut(50);
  try {
    //特殊处理
    let hasNestCategory = false;
    for (const [_, tab] of Object.entries(tabDefines.value)) {
      if (tab.type === 'nestCategory') {
        tab.categorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.categorys)
        hasNestCategory = true;
      } else if (tab.type === 'list') {
        tab.preInsertCategorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.preInsertCategorys || [])
        hasNestCategory = true;
      }
    }

    if (hasNestCategory)
      await waitTimeOut(50);

    //加载下拉列表
    const result = [] as DropDownNames[];
    for (const [key, tab] of Object.entries(tabRenderDefines.value)) {
      if (tab.type !== 'list')
        continue;
      if (tab.dropdownDefines) {
        for (const dropdown of tab.dropdownDefines) {    
          const data : SimpleDropDownPickerItem[] = (dropdown.addAll ? [{
            id: 0, 
            name: dropdown.addAll
          }] : []);
          if (dropdown.data) {
            data.push(...(await doLoadDynamicDropdownData(dropdown.data)).map((item) => ({
              id: item[dropdown.data.idKey || 'id'],
              name: item[dropdown.data.nameKey || 'title'],
            })))
          }
          result.push({
            options: data,
            activeTab: [Number(key)],
            defaultSelectedValue: dropdown.formQueryKey ? (
              props.pageQuerys[dropdown.formQueryKey] as number || 0
            ) : dropdown.defaultValue || 0,
          })
        }
      }
    }
    dropdownNames.value = result;
  } catch (error) {
    emit('error', error);
  } finally {
    loading.value = false;
  }
}

watch(() => props.currentCommonCategoryDefine, loadPageConfig, { immediate: true });
watch(() => props.currentCommonCategoryDefine?.content, loadPageConfig);
watch(() => props.currentCommonCategoryContentDefine, loadPageConfig);
onMounted(loadPageConfig);

type RenderTabDefine = IHomeCommonCategoryListTabDefine & {
  categoryDefine?: CategoryDefine[];  
};

const tabDefines = computed(() => props.currentCommonCategoryContentDefine?.props.tabs || []);
const tabRenderDefines = computed(() => {
  const result = {} as Record<number, RenderTabDefine>;
  try {
    tabDefines.value.forEach((item, i) => {
      const renderItem : RenderTabDefine = {
        ...item,
      };
      function loadNestCategoryData(items: IHomeCommonCategoryListTabNestCategoryItemDefine[]) {
        return items
          .filter((item) => item.visible !== false)
          .map((item) => {
            return {
              ...item,
              showTitle: item.showTitle !== false,
              title: item.text,
              content: item.data,
              type: item.type as CategoryDefine['type'],
            }
          });
      }
      switch (item.type) {
        case 'list':
          renderItem.categoryDefine = loadNestCategoryData(item.preInsertCategorys || []);
          break;
        case 'jump':
          break;
        case 'nestCategory':
          renderItem.categoryDefine = loadNestCategoryData(item.categorys);
          break;
      }
      result[i] = renderItem;
    });
  } catch (error) {
    emit('error', error);
  }
  return result;
});
const showListTabIds = computed(() => {
  const define = tabDefines.value;
  if (define.length === 0)
    return undefined;
  return define
    .map((item, i) => ({ type: item.type, id: i }))
    .filter((item) => item.type === 'list')
    .map((item) => item.id);
})
const tabs = computed<CommonListPageProps['tabs']>(() => {
  const define = tabDefines.value;
  return define.filter((item) => item.visible !== false).map((item, i) => {
    switch (item.type) {
      default:
      case 'list':
        return {
          id: i,
          text: item.text,
          width: item.width,
        };
      case 'jump':
        return {
          id: i,
          text: item.text,
          onlyJump: true,
          jump: () => navTo(item.url, item.params),
          width: item.width,
        };
      case 'nestCategory':
        return {
          id: i,
          text: item.text,
          width: item.width,
        };
    }
  });
});
const dropdownNames = ref<DropDownNames[]>([]);
const detailsPage = computed(() => {
  if (tabDefines.value.find((item) => item.detailsPage)) {
    const result = {} as Record<number, string|[string, Record<string, any>]>;
    tabDefines.value.forEach((item, i) => {
      result[i] = item.detailsPage || '';
    });
    return result;
  }
  return props.currentCommonCategoryContentDefine?.props.detailsPage || undefined;
});
const itemType = computed(() => {
  return props.currentCommonCategoryContentDefine?.props.itemType || 'article-common';
});
const detailsParams = ref<Record<string, any>>({});
const currentParentData = ref<any[]>([]);

async function loadData(
  page: number, 
  pageSize: number,
  searchText: string,
  dropDownValues: number[],
  tabSelect: number
) {
  const tab = tabRenderDefines.value[tabSelect];
  if (!tab) 
    throw new Error(`配置有误 tab:${tabSelect}`);
  if (tab.type !== 'list')
    return { list: [], total: 0 };
  if (!tab.data) 
    throw new Error(`配置有误 tab:${tabSelect} 没有配置列表数据`);
  detailsParams.value = {
    ...(doGetDynamicListDataParams(tab.data)),
  };
  const res = await doLoadDynamicListData(
    tab.data, 
    page, 
    pageSize, 
    searchText, 
    tab.dropdownDefines || [],
    dropDownValues,
    props.parentData,
  );
  if (res && tab.dataSolve)
    res.list = resolveCommonContentSolveProps(res.list, tab.dataSolve);
  currentParentData.value = res?.list || [];
  return res;
}
</script>