<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"
      :noInternalTabs="true"
      :showHead="currentCommonCategoryContentDefine?.props.showHead"
      :showDeadBox="currentCommonCategoryContentDefine?.props.showDeadBox"
      :load="load"
      :tabs="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 ">
            {{ appConfiguration?.articleMark }}
            {{ 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="currentCommonCategoryContentDefine?.props.showTag && 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 { navTo } from '@/components/utils/PageAction';
import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
import { injectCommonCategory } from './CommonCategoryGlobalLoader';
import { doLoadDynamicCategoryDataMergeTypeGetColumns, doLoadDynamicDetailData, doSerializeInternalVar, type IHomeCommonCategoryDynamicData } from './CommonCategoryDynamicData';
import { formatError, StringUtils, waitTimeOut } from '@imengyu/imengyu-utils';
import { getIsDevtoolsPlatform } from '@/common/utils/MpVersions';
import type { IHomeCommonCategoryDefine, IHomeCommonCategoryListTabListDataSolve, IHomeCommonCategoryListTabNestCategoryItemDefine } from './CommonCategoryDefine';
import type { IHomeCommonCategoryDetailDefine, IHomeCommonCategoryDetailTabItemDefine } from './defines/Details';
import type { DetailTabPageProps } from '../common/DetailTabPage';
import type { CategoryDefine } from './CommonCategoryBlocks';
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 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, { GetContentDetailItem, GetContentListParams } from '@/api/CommonContent';
import CommonCategoryDetailContentBlocks from './CommonCategoryDetailContentBlocks.vue';
import ImageGrid from '@/pages/parts/ImageGrid.vue';
import CommonCategoryListBlock from './CommonCategoryListBlock.vue';
import { resolveCommonContentSolveProps } from '../common/CommonContent';
import { getDynamicScript, isDynamicScript } from './CommonCategoryScript';

export interface CommonCategoryDetailProps extends DetailTabPageProps {
  /**
   * 简介块描述项
   */
  introBlockDescs?: {
    label: string;
    key: string;
    map?: Record<string|number, string>;
    visibleVia?: string;
  }[];
  /**
   * 简介下方块
   */
  introBlocks?: CommonCategoryDetailIntroBlocksDesc[];
  /**
   * 是否显示级别标签
   */
  showTag?: boolean;
  /**
   * 是否显示死亡框
   */
  showDeadBox?: boolean;
  /**
   * 自定义数据接口
   */
  data?: IHomeCommonCategoryDynamicData;
  /**
   * 内容处理
   */
  dataSolve?: IHomeCommonCategoryListTabListDataSolve[];
}
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 appConfiguration = injectAppConfiguration();

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

const tabDefines = ref<IHomeCommonCategoryDetailTabItemDefine[]>([]);
const tabVisibles = ref<boolean[]>([]);
const tabRenderDefines = computed(() => {
  const result = {} as Record<number, RenderTabDefine>;
  try {
    tabDefines.value.forEach((item, i) => {
      const renderItem : RenderTabDefine = {
        ...item,
        visible: tabVisibles.value[i],
        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: item.data,
              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) {
    await waitTimeOut(1000);
    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 || '',
  })

  const tabs = currentCommonCategoryContentDefine.value?.props.tabs || [];

  await waitTimeOut(50);
  
  try {
    //特殊处理
    let hasNestCategory = false;
    for (const tab of tabs) {
      if (tab.type === 'nestCategory') {
        tab.categorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.categorys)
        hasNestCategory = true;
      }
    }
    if (hasNestCategory)
      await waitTimeOut(50);
    loadState.value = true;
    await waitTimeOut(50);
    const content = (await pageRef.value?.load(props.pageQuerys)) as GetContentDetailItem;

    //Tab标签动态处理
    function loadByContentData(text: string) {
      let result = text;
      const keys = text.split(':');
      if (keys.length >= 2) {
        switch (keys[1]) {
          case 'byContentType': 
            switch(content.type) {
              default:
              case GetContentListParams.TYPE_ARTICLE: result = '相关文章'; break;
              case GetContentListParams.TYPE_VIDEO: result = '视频'; break;
            }
            break;
          case 'bySubListType':  {
            const subListKey = keys[2];
            if (subListKey) {
              const list = content?.[subListKey];
              if (Array.isArray(list) && list.length > 0) {
                switch(list[0].type) {
                  default:
                  case GetContentListParams.TYPE_ARTICLE: result = '相关文章'; break;
                  case GetContentListParams.TYPE_ARCHIVE: result = '相关文档'; break;
                  case GetContentListParams.TYPE_VIDEO: result = '视频'; break;
                  case GetContentListParams.TYPE_IMAGE: result = '相册'; break;
                }
              } else {
                result = '相关';
              }
            }
            break;
          }
          case 'expression': {
            result = getDynamicScript().execute(keys[2], {
              main: content,
              customData: {
                customTabNameIdMap: currentCommonCategoryContentDefine.value?.props.customTabNameIdMap || {},
              },
            }) as any;
            break;
          }
          case 'idMap': {
            if (currentCommonCategoryContentDefine.value?.props.customTabNameIdMap) {
              result = currentCommonCategoryContentDefine.value.props.customTabNameIdMap[content.id];
            }
          }
        }
      }
      return result;
    }
    for (const tab of tabs) {
      if (tab.text.startsWith('dynamic')) {
        tab.text = loadByContentData(tab.text);
      }
    }
    await loadTabVisible(tabs, content);

  } catch (error) {
    console.error(error);
    loadState.value = false;
    errorMessage.value = formatError(error);
  }

  tabDefines.value = tabs;
}

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

const content = ref<any>();
const descItems = computed(() => (
  currentCommonCategoryContentDefine.value?.props.introBlockDescs || [])
    .map((item) => {
      let value = '';
      if (item.key.startsWith('expression:')) {
        value = getDynamicScript().execute(item.key.substring(11), {
          main: content.value,
        }) as any;
      }
      else
        value = content.value?.[item.key] || '';
      if (item.map)
        value = item.map[value] || '';
      return {
        ...item,
        value,
      }
    })
    .filter((item) => Boolean(item.value))
    .filter((item) => !item.visibleVia || item.visibleVia === 'auto' || getDynamicScript().execute(item.visibleVia, {
      main: item,
    }) as any)
);

function onLoaded(d: any) {
  content.value = d;
}
async function loadTabVisible(tabs: IHomeCommonCategoryDetailTabItemDefine[], d: any) {
  if (!d)
    return;
  for (let i = 0; i < tabs.length; i++) {
    const tab = tabs[i];
    const v = d[tab.key];
    let check = true
    let visibleCheckBy = 'auto';
    let visibleCheckKeys = [] as string[];
    let visibleCheckExpression = '';
    if (tab.visibleVia && tab.visibleVia.includes(':')) {
      visibleCheckKeys = tab.visibleVia.split(':');
      visibleCheckBy = visibleCheckKeys[0];
    } else if (tab.visibleVia && isDynamicScript(tab.visibleVia)) {
      visibleCheckExpression = tab.visibleVia;
      visibleCheckBy = 'expression';
    }
    switch (visibleCheckBy) {
      default:
      case 'auto': {
        switch (tab.type) {
          case 'intro': check = true; break;
          case 'audio': check = Boolean(d.audio); break;
          case 'video': check = Boolean(d.video); break;
          case 'images': check = Boolean(d.images) && (d.images as string[]).length > 1; break;
          case 'map': check = Boolean(d.latitude) && Boolean(d.longitude); break;
          default: 
            if (!v)
              check = false;
            else if (Array.isArray(v))
              check = (v as any[]).length > 0;
            break;
        }
        break;
      }
      case 'expression': {
        check = getDynamicScript().execute(visibleCheckExpression, {
          main: d,
        }) as any;
        break;
      }
      case 'idMap': {
        const idMap = currentCommonCategoryContentDefine.value?.props.customTabVisibleViaIdMap;
        if (idMap && visibleCheckKeys.length >= 2)
          check = idMap[`${d.id}:${visibleCheckKeys[1]}`];
        break;
      }
    }
    tabVisibles.value[i] = tab.visible !== false && check;
  }
}
async function load(id: number) {
  if (isNaN(id) || id <= 0)
    throw new Error("请输入ID。如果正在测试，可在后台复制ID");
  if (currentCommonCategoryContentDefine.value?.props.data) {
    return await doLoadDynamicDetailData(
      currentCommonCategoryContentDefine.value?.props.data,
      id,
      props.pageQuerys.modelId && Number(props.pageQuerys.modelId) > 0 ? Number(props.pageQuerys.modelId) : undefined
    );
  }
  let res = await CommonContent.getContentDetail(
    id, 
    undefined, 
    props.pageQuerys.modelId && Number(props.pageQuerys.modelId) > 0 ? Number(props.pageQuerys.modelId) : undefined
  );
  if (currentCommonCategoryContentDefine.value?.props.dataSolve) {
    res = resolveCommonContentSolveProps([ res ], currentCommonCategoryContentDefine.value.props.dataSolve)[0];
  }
  return res;
}
function handleGoToVr(vr: string) {
  navTo('/pages/article/web/ewebview', { url: vr })
}

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