<template>
  <!--通用内容首页小分块组件-->
  <FlexCol width="100%">
    <!-- 分类 -->
    <FlexCol 
      v-for="(category,i) in categoryDatas" :key="i"
      :innerStyle="category.style"
    >
      <HomeTitle 
        v-if="category.showTitle"
        :title="category.title"
        :titleLevel="category.textLevel"
        :showMore="category.showMore !== false"
        :moreText="category.moreText || '更多'"
        @clickMore="category.morePage" 
      />
      <!--预制块-->
      <template v-if="category.type === 'CalendarBlock'">
        <CalendarBlock v-bind="category.blockProps" />
      </template>
      <template v-else-if="category.type === 'StatsBlock'">
        <StatsBlock v-bind="category.blockProps" />
      </template>
      <template v-else-if="category.type === 'MapBlock'">
        <MapCategoryBlock v-bind="category.blockProps" />
      </template>
      <template v-else-if="category.type === 'AudioBlock'">
        <AudioBlock v-bind="category.blockProps" />
      </template>
      <template v-else-if="category.type === 'RichBlock'">
        <RichBlock v-bind="category.blockProps" />
      </template>
      <!--通用列表-->
      <SimplePageContentLoader v-else-if="category.data" :loader="category.data" >
        <FlexCol>
          <template v-if="category.type === 'simple-article'">
            <FlexCol :margin="[10, 0]">
              <Box2LineRightShadow
                v-for="(item, i) in category.data.content.value" 
                :key="i" 
                :title="item.title"
                :titleBox="item.titleBox"
                :desc="item.desc"
                :tags="(item.bottomTags as string[])"
                @click="category.detailsPage(item)"
              />
            </FlexCol>
          </template>
          <template v-else-if="category.type === 'large-image'">
            <FlexCol>
              <Box2LineLargeImageUserShadow
                v-for="(item, i) in category.data.content.value"
                titleColor="title-text"
                fixSize
                title1
                :key="i"
                :title="item.title"
                :titleBox="Boolean(item.titleBox)"
                :desc="item.desc"
                :image="item.image"
                :tags="(item.bottomTags as string[])"
                @click="category.detailsPage(item)"
              />
            </FlexCol>
          </template>
          <template v-else-if="category.type === 'large-image2'">
            <scroll-view scroll-x>
              <FlexRow>
                <Box2LineLargeImageUserShadow
                  v-for="(item, i) in category.data.content.value"
                  classNames="width-2-3 mr-2"
                  titleColor="title-text"
                  fixSize
                  title1
                  :key="i"
                  :title="item.title"
                  :titleBox="Boolean(item.titleBox)"
                  :desc="item.desc"
                  :image="item.image"
                  :tags="(item.bottomTags as string[])"
                  @click="category.detailsPage(item)"
                />
              </FlexRow>
            </scroll-view>
          </template>
          <template v-else-if="category.type === 'horizontal-large'">
            <scroll-view scroll-x>
              <view class="pb-3 pt-3 d-flex flex-row overflow-visible align-stretch">
                <Box2LineLargeImageUserShadow
                  v-for="(item, i) in category.data.content.value"
                  classNames="width-2-3 mr-2"
                  titleColor="title-text"
                  title1
                  fixSize
                  :key="i"
                  :title="item.title"
                  :titleBox="Boolean(item.titleBox)"
                  :desc="item.desc"
                  :image="item.thumbnail || item.image"
                  :tags="(item.bottomTags as string[])"
                  @click="category.detailsPage(item)"
                />
              </view>
            </scroll-view>
          </template>
          <template v-else-if="category.type === 'large-grid2'">
            <FlexRow wrap align="stretch" justify="space-between" overflow="visible">
              <Box2LineLargeImageUserShadow
                v-for="(item, i) in category.data.content.value"
                titleColor="title-text"
                width="calc(50% - 10rpx)"
                fixSize
                :key="i"
                :title="item.title"
                :titleBox="Boolean(item.titleBox)"
                :desc="item.desc"
                :image="item.image"
                :tags="(item.bottomTags as string[])"
                @click="category.detailsPage(item)"
              />
            </FlexRow>
          </template>
          <template v-else-if="category.type === 'small-grid2'">
            <FlexRow wrap justify="space-between" align="stretch">
              <Grid4Item 
                v-for="(tab, k) in category.data.content.value"
                :key="k"
                :title="tab.title"
                :image="tab.thumbnail || tab.image"
                classNames="half"
                @click="category.detailsPage(tab)"
              />
            </FlexRow>
          </template>
          <template v-else-if="category.type === 'small-grid'">
            <FlexCol :gap="10" align="center">
              <Grid4Item 
                v-for="(tab, k) in category.data.content.value"
                :key="k"
                :title="tab.title"
                :image="tab.thumbnail || tab.image"
                classNames="full"
                @click="category.detailsPage(tab)"
              />
            </FlexCol>
          </template>
          <template v-else-if="category.type === 'simple-text'">
            <FlexCol>
              <Box2LineImageRightShadow
                v-for="(item, i) in category.data.content.value"
                titleColor="title-text"
                :border="false"
                fixSize
                :key="i"
                :title="item.title"
                :titleBox="Boolean(item.titleBox)"
                :desc="item.desc"
                :showImage="false"
                :tags="(item.bottomTags as string[])"
              />
            </FlexCol>
          </template>
          <template v-else-if="category.type === 'article'">
            <Box2LineImageRightShadow
              v-for="(item, i) in category.data.content.value"
              titleColor="title-text"
              fixSize
              wideImage
              :key="i"
              :title="item.title"
              :titleBox="Boolean(item.titleBox)"
              :desc="item.desc"
              :image="item.image"
              :tags="(item.bottomTags as string[])"
              @click="category.detailsPage(item)"
            />
          </template>
          <template v-else>
            <Box2LineImageRightShadow
              v-for="(item, i) in category.data.content.value"
              titleColor="title-text"
              fixSize
              :key="i"
              :title="item.title"
              :titleBox="Boolean(item.titleBox)"
              :desc="item.desc"
              :image="item.image"
              :tags="(item.bottomTags as string[])"
              @click="category.detailsPage(item)"
            />
          </template>
        </FlexCol>
      </SimplePageContentLoader>  
    </FlexCol>
  </FlexCol>
</template>

<script setup lang="ts">;
import { computed, onMounted, watch, type PropType } from 'vue';
import CommonContent, { GetContentListItem, GetContentListParams } from '@/api/CommonContent';
import { navCommonDetail, navCommonList, navigateToAutoContent, resolveCommonContentGetPageDetailUrlAuto, resolveCommonContentSolveProps } from '../common/CommonContent';
import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
import { navTo } from '@/components/utils/PageAction';
import HomeTitle from '@/pages/parts/HomeTitle.vue';
import SimplePageContentLoader from '@/common/components/SimplePageContentLoader.vue';
import Box2LineImageRightShadow from '@/pages/parts/Box2LineImageRightShadow.vue';
import Box2LineRightShadow from '@/pages/parts/Box2LineRightShadow.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import FlexRow from '@/components/layout/FlexRow.vue';
import CalendarBlock from '@/pages/travel/calendar/block.vue';
import Box2LineLargeImageUserShadow from '@/pages/parts/Box2LineLargeImageUserShadow.vue';
import StatsBlock from '@/pages/blocks/StatsBlock.vue';
import MapCategoryBlock from '@/pages/blocks/MapBlock.vue';
import Grid4Item from '@/pages/parts/Grid4Item.vue';
import type { CategoryDefine } from './CommonCategoryBlocks';
import { CommonCategoryDynamicDataSerializedApi, doGetDynamicListDataParams, type IHomeCommonCategoryDynamicDataDetailContent } from './CommonCategoryDynamicData';
import AudioBlock from '@/pages/blocks/AudioBlock.vue';
import RichBlock from '@/pages/blocks/RichBlock.vue';
import { doDynamicNavDetails } from '../common/CommonListPage';
import { getDynamicScript, isDynamicScript } from './CommonCategoryScript';

const props = defineProps({
  /**
   * 分类定义
   */
  categoryDefine: {
    type: Array as PropType<CategoryDefine[]>,
    default: () => [],
  },
  /**
   * 父级数据
   */
  parentData: {
    type: Object as PropType<any>,
    default: () => {},
  },
});

const categoryDatas = computed(() => props.categoryDefine.map(item => { 
  if (!item.content)
    return {
      ...item,
      detailsPage: () => {},
      morePage: () => {
        if (item.morePage && isDynamicScript(item.morePage))
          doDynamicNavDetails(item.morePage, {}, props.parentData);
        else if (item.morePage)
          navTo(item.morePage, {});
      },
      data: null,
    };
  return {
    ...item,
    detailsPage: (dataItem: GetContentListItem) => {
      const id = dataItem.id;
      let modelId = 0;
      let mainBodyColumnId : string|number|number[]|undefined = undefined;
      switch (item.data.type) {
        case 'commonContent':
        case 'serializedApi': {
          const params = doGetDynamicListDataParams(item.data);
          modelId = params.modelId;
          mainBodyColumnId = params.mainBodyColumnId;
          break;
        }
      }  

      const params = { id, mainBodyColumnId, modelId };
      if (item.detailsPage) {
        if (item.detailsPage === 'disabled')
          return;
        else if (item.detailsPage === 'byContent')
          navigateToAutoContent(dataItem, params);
        else if (item.detailsPage && isDynamicScript(item.detailsPage)) {
          doDynamicNavDetails(item.detailsPage, dataItem, props.parentData);
          return;
        }
        else
          navTo(item.detailsPage, params);
      } else {
        navCommonDetail(params);
      }
    },
    morePage: () => {
      if (item.morePage === 'disabled') {
        return;
      } else if (item.morePage) {
        navTo(item.morePage, {});
      } else {
        let modelId = 0;
        let mainBodyColumnId : string|number|number[]|undefined = undefined;
        switch (item.data.type) {
          case 'commonContent':
          case 'serializedApi': {
            const params = doGetDynamicListDataParams(item.data);
            modelId = params.modelId;
            mainBodyColumnId = params.mainBodyColumnId;
            break;
          }
        }  
        if (item.morePage && isDynamicScript(item.morePage)) {
          getDynamicScript().execute(item.morePage, {
            main: {
              modelId,
              mainBodyColumnId,
            },
          });
          return;
        }
        navCommonList({
          title: item.title,
          mainBodyColumnId: mainBodyColumnId,
          modelId: modelId,
          detailsPage: item.detailsPage,
          dataSolve: item.dataSolve || [],
          itemType: item.itemType,
        })
      }
    },
    data: useSimpleDataLoader(async () => {
      let res : any[] = [];
      const params = new GetContentListParams();
      switch (item.data.type) {
        case 'commonContent': {
          params.setModelId(item.data.params.modelId);
          if (item.data?.otherParams)
            params.setSelfValues(item.data.otherParams);
          if (item.data.params?.mainBodyColumnId)
            params.setMainBodyColumnId(item.data.params.mainBodyColumnId);
          res = (await CommonContent
            .getContentList(params, 1, item.count || 4))
            .list;
          break;
        }
        case 'serializedApi': {
          if (item.data.params?.mainBodyColumnId)
            params.setMainBodyColumnId(item.data.params.mainBodyColumnId);
          if (item.data?.otherParams)
            params.setSelfValues(item.data.otherParams);
          res = (await CommonCategoryDynamicDataSerializedApi(item.data)
            .getContentList(params, 1, item.count || 4))
            .list;
          break;
        }
        case 'detailContent': {
          const data = item.data as IHomeCommonCategoryDynamicDataDetailContent;
          res = [ await CommonContent.getContentDetail(data.params!.id, undefined, data.params!.modelId || undefined) ];
          break;
        }
        case 'parentKey': {
          if (!props.parentData)
            throw new Error('父级数据未设置');
          res = props.parentData[item.data.key];
          break;
        }
        case 'staticData': {
          res = item.data.data;
          break;
        }
        case 'request': {
          res = (await CommonContent.request(
            item.data.url, 
            { 
              page: 1,
              pageSize: item.count || 4,
              ...item.data.querys, 
            }, 
            {
              method: item.data.method, 
              data: item.data.otherParams,
            },
            '',
            undefined,
          )).data as unknown as any[];
          break;
        }
        default:
          throw new Error(`未实现的动态数据接口 ${(item.data as any).type}`);
      }
      return resolveCommonContentSolveProps(res, item.dataSolve || []);
    }, false)
  }
}));

function loadCategoryDatas() {
  categoryDatas.value.forEach(item => {
    if (item.data)
      item.data.loadData(undefined, true);
  })
}

watch(categoryDatas, loadCategoryDatas);
onMounted( loadCategoryDatas);
</script>