<template>
  <!--详情页可配置主控-->
  <FlexCol>
    <FlexCol v-if="errorMessage" :padding="30" :gap="30" center height="100%">
      <Result status="error" :description="errorMessage" />
      <Button type="primary" @click="loadPageConfig">重新加载</Button>
    </FlexCol>
    <LoadingPage v-else-if="!loadState" />
    <DetailTabPage
      v-else
      ref="pageRef"
      v-bind="$attrs"
      :noInternalTabs="true"
      :load="load"
      :extraTabs="tabRenderDefinesArray"
      @loaded="onLoaded"
    >
      <template #extraTabs="{ content, tabCurrentId }">
        <template v-if="tabRenderDefines[tabCurrentId].type === 'intro'">
          <!-- 简介 -->
          <Parse
            v-if="content.intro"
            :content="(content.intro as string)"
          />
          <Parse
            v-if="content.content"
            :content="content.content"
          />
          <text v-if="!(content.intro || content.content)">暂无简介</text>
          <text v-if="content.from" class="size-s color-text-content-second mr-2 ">以上内容摘自 {{ content.from }}</text>
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'images'">
          <!-- 图片 -->
          <view v-if="tabRenderDefines[tabCurrentId].prefix" class="d-flex flex-row justify-center align-center mt-2 mb-2">
            <text class="size-s font-bold color-text-content">{{ tabRenderDefines[tabCurrentId].prefix }}</text>
          </view>
          <ImageGrid
            :images="content.images"
            :rowCount="2"
            :preview="true"
            imageHeight="200rpx"
          />
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'video'">
          <!-- 视频 -->
          <video
            v-if="content.video"
            class="w-100 video"
            autoplay
            :poster="content.image"
            :src="content.video"
            controls
          />
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'audio'">
          <!-- 视频 -->
          <video
            v-if="content.audio"
            class="w-100 video"
            autoplay
            :poster="content.image"
            :src="content.audio"
            controls
          />
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'list'">
          <!-- 列表 -->
          <CommonCategoryListBlock
            v-if="currentCommonCategoryDefine"
            :currentCommonCategoryDefine="{ 
              title: '',
              name: 'default',
              content: tabRenderDefines[tabCurrentId].define
            }"
            :currentCommonCategoryContentDefine="tabRenderDefines[tabCurrentId].define"
            :pageQuerys="pageQuerys"
            :parentData="content"
            :hasPadding="false"
            :hasBg="false"
            @error="errorMessage = $event"
          />
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'rich'">
          <!-- 富文本 -->
          <view class="d-flex flex-col mt-3 mb-2">
            <Parse :content="(content[tabRenderDefines[tabCurrentId].key] as string)" />
          </view>
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].type === 'nestCategory'">
          <!-- 嵌套分类 -->
          <CommonCategoryBlocks :categoryDefine="tabRenderDefines[tabCurrentId].categoryDefine" />
        </template>
        <template v-else-if="tabRenderDefines[tabCurrentId].key === 'vr'">
          <!-- VR参观 -->
          <view class="d-flex flex-row justify-center p-5">
            <Button @click="handleGoToVr(content.vr as string)">
              <text class="iconfont icon-go"></text>
              点击参观
            </Button>
          </view>
        </template>
        <template v-else>
          <CommonCategoryDetailContentBlocks
            :define="tabRenderDefines[tabCurrentId]"
            :content="content"
          />
        </template>
      </template>
      <template #titleEnd="{ content }">
        <Tag
          v-if="content.levelText"
          :text="StringUtils.cutString(content.levelText as string, 4)"
          size="small" scheme="light" type="primary"
          class="flex-shrink-0"
        />
      </template>
      <template #titleExtra="{ content }">
        <view class="d-flex flex-col">
          <IntroBlock small :descItems="descItems" />
          <CommonCategoryDetailIntroBlocks
            :introBlocks="currentCommonCategoryContentDefine?.props.introBlocks"
            :content="content"
          />
        </view>
      </template>
    </DetailTabPage>
  </FlexCol>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import LoadingPage from '@/components/display/loading/LoadingPage.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import Result from '@/components/feedback/Result.vue';
import Button from '@/components/basic/Button.vue';
import { CommonCategoryListTabNestCategoryDataToContent, type IHomeCommonCategoryDefine, type IHomeCommonCategoryListTabNestCategoryItemDefine } from './CommonCategoryDefine';
import { injectCommonCategory } from './CommonCategoryGlobalLoader';
import { doLoadDynamicCategoryDataMergeTypeGetColumns } from './CommonCategoryDynamicData';
import { formatError, StringUtils, waitTimeOut } from '@imengyu/imengyu-utils';
import type { IHomeCommonCategoryDetailDefine, IHomeCommonCategoryDetailTabItemDefine } from './defines/Details';
import type { DetailTabPageProps, DetailTabPageTabsArray } from '../common/DetailTabPage';
import type { CategoryDefine } from './CommonCategoryBlocks';
import DetailTabPage from '../common/DetailTabPage.vue';
import IntroBlock from '../common/IntroBlock.vue';
import CommonCategoryDetailIntroBlocks from './CommonCategoryDetailIntroBlocks.vue';
import Tag from '@/components/display/Tag.vue';
import CommonCategoryBlocks from './CommonCategoryBlocks.vue';
import Parse from '@/components/display/parse/Parse.vue';
import CommonContent from '@/api/CommonContent';
import CommonCategoryDetailContentBlocks from './CommonCategoryDetailContentBlocks.vue';
import ImageGrid from '@/pages/parts/ImageGrid.vue';
import CommonCategoryListBlock from './CommonCategoryListBlock.vue';
import { navTo } from '@/components/utils/PageAction';

export interface CommonCategoryDetailProps extends DetailTabPageProps {
  /**
   * 简介块描述项
   */
  introBlockDescs?: {
    label: string;
    key: string;
    map?: Record<string|number, string>;
  }[];
  /**
   * 简介下方块
   */
  introBlocks?: CommonCategoryDetailIntroBlocksDesc[];
}
export interface CommonCategoryDetailIntroBlocksDesc {
  type: string;
  props?: Record<string, any>;
}
export type RenderTabDefine = IHomeCommonCategoryDetailTabItemDefine & {
  id: number;
  categoryDefine?: CategoryDefine[];  
};

const pageRef = ref();
const props = defineProps({
  pageConfigName: {
    type: String,
  },
  pageQuerys: {
    type: Object as () => Record<string, string|number|number[]|undefined>,
    default: () => ({}),
  },
})

const loadState = ref(false);
const errorMessage = ref('');
const currentCommonCategoryDefine = ref<IHomeCommonCategoryDefine['page'][0]>();
const currentCommonCategoryContentDefine = ref<IHomeCommonCategoryDetailDefine>();
const commonCategory = injectCommonCategory();

const tabDefines = computed(() => currentCommonCategoryContentDefine.value?.props.tabs || []);
const tabRenderDefines = computed(() => {
  const result = {} as Record<number, RenderTabDefine>;
  try {
    tabDefines.value.forEach((item, i) => {
      const renderItem : RenderTabDefine = {
        ...item,
        id: i,
      };
      function loadNestCategoryData(items: IHomeCommonCategoryListTabNestCategoryItemDefine[]) {
        return items
          .filter((item) => item.visible !== false)
          .map((item) => {
            return {
              ...item,
              showTitle: item.showTitle !== false,
              title: item.text,
              content: CommonCategoryListTabNestCategoryDataToContent(
                item.data, item
              ),
              type: item.type as CategoryDefine['type'],
            }
          });
      }
      switch (item.type) {
        case 'nestCategory':
          renderItem.categoryDefine = loadNestCategoryData(item.categorys);
          break;
      }
      result[i] = renderItem;
    });
  } catch (error) {
    errorMessage.value = formatError(error);
  }
  return result;
});
const tabRenderDefinesArray = computed(() => {
  return Object.values(tabRenderDefines.value);
});

async function loadPageConfig() {
  if (!props.pageConfigName) {
    errorMessage.value = '配置有误';
    return;
  }
  currentCommonCategoryDefine.value = commonCategory.value.page
    .find((item) => item.name === props.pageConfigName);
  if (!currentCommonCategoryDefine.value) {
    errorMessage.value = '未找到指定的分类配置：' + props.pageConfigName;
    return;
  }
  if (currentCommonCategoryDefine.value.content.type !== 'Details') {
    errorMessage.value = '分类配置：' + props.pageConfigName + ' 不是详情类型';
    return;
  }
  currentCommonCategoryContentDefine.value = 
    currentCommonCategoryDefine.value.content as IHomeCommonCategoryDetailDefine;
  uni.setNavigationBarTitle({
    title: currentCommonCategoryDefine.value?.title || '',
  })

  await waitTimeOut(100);
  
  try {
    //特殊处理
    let hasNestCategory = false;
    for (const [_, tab] of Object.entries(tabDefines.value)) {
      if (tab.type === 'nestCategory') {
        tab.categorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.categorys)
        hasNestCategory = true;
      }
    }
    if (hasNestCategory)
      await waitTimeOut(100);
    loadState.value = true;
    await waitTimeOut(100);
    pageRef.value?.load(props.pageQuerys);
  } catch (error) {
    console.error(error);
    loadState.value = false;
    errorMessage.value = formatError(error);
  }
}

watch(() => props.pageConfigName, loadPageConfig);
onMounted(loadPageConfig);

const content = ref<any>();
const descItems = computed(() => (
  currentCommonCategoryContentDefine.value?.props.introBlockDescs || [])
    .map((item) => {
      let value = content.value?.[item.key] || '';
      if (item.map)
        value = item.map[value] || '';
      return {
        ...item,
        value,
      }
    })
);

function onLoaded(d: any) {
  content.value = d;
}
async function load(id: number, tabsArray: DetailTabPageTabsArray) {
  if (isNaN(id) || id <= 0)
    throw new Error("请输入ID。如果正在测试，可在后台复制ID");
  const d = await CommonContent.getContentDetail(
    id, 
    undefined, 
    props.pageQuerys.modelId && Number(props.pageQuerys.modelId) > 0 ? Number(props.pageQuerys.modelId) : undefined
  );
  for (const tab of tabRenderDefinesArray.value) {
    const v = d[tab.key];
    let check = true
    if (['intro','map'].includes(tab.type))
      check = true;
    else if (tab.type === 'audio')
      check = Boolean(d.audio);
    else if (tab.type === 'video')
      check = Boolean(d.video);
    else if (tab.type === 'images')
      check = Boolean(d.images) && (d.images as string[]).length > 0;
    else if (!v)
      check = false;
    else if (Array.isArray(v))
      check = (v as any[]).length > 0;
    tabsArray.getTabById(tab.id)!.visible = tab.visible !== false && check;
  }
  return d;
}
function handleGoToVr(vr: string) {
  navTo('/pages/article/web/ewebview', { url: vr })
}

defineExpose({
  getPageShareData() {
    return pageRef.value?.getPageShareData() || {};
  } 
})
</script>
