<script setup lang="ts">
import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'

import { computed, onMounted, ref, watch } from 'vue'
import XReportJsonRender from './XReportJsonRender.vue'
import XReportTrGroup from './XReportTrGroup.vue'

// Props 类型定义
interface Props {
  config: {
    data: Record<string, any>
    designMode?: string
    width?: number
    title?: string
    style?: Record<string, string>
    columns?: any[][]
    subTitle?: Array<{
      type: string
      text?: string
      format?: string
      dataIndex?: string
      inputWidth?: number
      inputReadOnly?: boolean
    }>
  }
  showImgInCell?: boolean
  forDisplay?: boolean
  serverName?: string
  env?: string
  displayOnly?: boolean
  slotConfigName?: string
  showImages?: boolean
  imageList?: any[]
  noPadding?: boolean
  noTopBorder?: boolean
  showTitle?: boolean
  useOssForImg?: boolean
  imgPrefix?: string
}

// Props
const props = withDefaults(defineProps<Props>(), {
  serverName: 'af-system',
  env: 'prod',
  displayOnly: false,
  noPadding: true,
  noTopBorder: false,
  showTitle: true,
  useOssForImg: true,
})

// Emits
const emit = defineEmits(['updateImg', 'selectRow', 'slotRendered'])

// 注入
const isWidget = false // inject('isWidget', false)

// 状态
const data = ref(props.config.data || {})
const slotConfig = ref<any>()
const render = ref(false)
const activatedConfig = ref<any>({})

// 计算属性
const flexItemBodyState = computed(() => ({
  padding: isWidget ? '0px' : '24px',
}))

// 方法
function slotRendered() {
  emit('slotRendered')
}

function updateImg(data: any) {
  emit('updateImg', data)
}

function selectRow(selectedRowKeys: any[], selectedRows: any[]) {
  console.log('XReportDesign')
  emit('selectRow', selectedRowKeys, selectedRows)
}

// 格式化相关方法
function calcFormatInputNum(formatStr: string) {
  let count = 0
  for (let i = 0; i < formatStr.length; i++) {
    if (formatStr[i] === '{')
      count++
  }
  return count
}

function displayFormatText(formatStr: string, num: number) {
  let start = 0
  let count = 0
  num++
  for (let i = 0; i < formatStr.length; i++) {
    if (formatStr[i] === '}') {
      start = i
      count++
    }
    if (count === num) {
      for (let j = start + 1; j < formatStr.length; j++) {
        if (formatStr[j] === '{')
          return formatStr.slice(start + 1, j)

        if (j === formatStr.length - 1 && formatStr[j] !== '}')
          return formatStr[j]
      }
    }
  }
}

function displayFormatStartText(formatStr: string) {
  let count = 0
  for (let i = 0; i < formatStr.length; i++) {
    if (formatStr[i] === '{')
      break
    count++
  }
  return formatStr.slice(0, count)
}

// 生命周期
onMounted(() => {
  console.log('>>>> xreportdesign 渲染')
  if (props.slotConfigName) {
    getConfigByName(props.slotConfigName, (res: any) => {
      slotConfig.value = res
      res.data = { ...res.data, ...data.value }
      // eslint-disable-next-line vue/no-mutating-props
      props.config.data = res.data
      activatedConfig.value = res
      render.value = true
    }, props.serverName)
  }
  else {
    activatedConfig.value = props.config
    render.value = true
  }

  if (activatedConfig.value.designMode !== 'json') {
    activatedConfig.value.columns?.forEach((row: any[]) => {
      if (row[0]?.type === 'list' && row[0]?.listLength === 1) {
        row.forEach((cell) => {
          cell.listLength = activatedConfig.value.data[cell.dataIndex].length
        })
      }
    })
  }
})

// 监听
watch(() => props.config, () => {
  // 配置变化时的处理
}, { deep: true })

watch(() => activatedConfig.value, (val) => {
  console.log('>>>> activatedConfig: ', val)
})
</script>

<template>
  <div id="xreportdesign">
    <template v-if="activatedConfig.designMode === 'json'">
      <XReportJsonRender
        :img-prefix="imgPrefix"
        :server-name="serverName"
        :display-only="displayOnly"
        :show-title="showTitle"
        :no-padding="noPadding"
        :no-top-border="noTopBorder"
        :config="activatedConfig"
        @update-img="updateImg"
        @select-row="selectRow"
      />
    </template>
    <template v-else-if="isWidget">
      <template v-for="(row, rowIndex) in activatedConfig.columns">
        <!--  插槽展示  -->
        <template v-if="row[0].type === 'slot'">
          <XReportTrGroup
            :key="rowIndex"
            :show-img-in-cell="showImgInCell"
            :img-prefix="imgPrefix"
            :server-name="serverName"
            :env="env"
            :use-oss-for-img="useOssForImg"
            :columns="row"
            :no-top-border="noTopBorder"
            :config-data="activatedConfig.data"
            :config="activatedConfig"
            :display="true"
            @update-img="updateImg"
            @select-row="selectRow"
          />
        </template>
        <!--  普通行  -->
        <template v-else>
          <template v-if="!forDisplay">
            <XReportTrGroup
              :key="rowIndex"
              :show-img-in-cell="showImgInCell"
              :img-prefix="imgPrefix"
              :server-name="serverName"
              :env="env"
              :use-oss-for-img="useOssForImg"
              :columns="row"
              :no-top-border="noTopBorder"
              :config-data="activatedConfig.data"
              :config="activatedConfig"
              @update-img="updateImg"
            />
          </template>
          <template v-else>
            <XReportTrGroup
              :key="rowIndex"
              :show-img-in-cell="showImgInCell"
              :img-prefix="imgPrefix"
              :server-name="serverName"
              :env="env"
              :use-oss-for-img="useOssForImg"
              :config="activatedConfig"
              :columns="row"
              :no-top-border="noTopBorder"
              :config-data="activatedConfig.data"
              :display="true"
              @update-img="updateImg"
              @select-row="selectRow"
            />
          </template>
        </template>
      </template>
    </template>
    <template v-else>
      <div :class=" noPadding ? 'reportMainNoPadding' : 'reportMain'" :style="activatedConfig.width > 0 ? (`width:${activatedConfig.width}px`) : undefined">
        <!--      大标题      -->
        <h2 v-if="showTitle && activatedConfig.title" class="reportTitle" v-html="activatedConfig.title" />
        <!--      小标题 / 介乎于标题与表格之间的内容      -->
        <div v-if="activatedConfig.subTitle && activatedConfig.subTitle.length" class="subTitle">
          <div v-for="(item, itemIndex) in activatedConfig.subTitle" :key="itemIndex" class="subTitleItems">
            <template v-if="item.type === 'column'">
              <span>{{ item.text }}</span>
            </template>
            <template v-else-if="item.type === 'inputs'">
              <div class="inputsDiv">
                <div v-for="(num, index) of calcFormatInputNum(item.format)" :key="index" class="inputsDivItem">
                  <span class="inputsDivItemLabel">{{ displayFormatStartText(item.format) }}</span>
                  <template v-if="!forDisplay">
                    <template v-if="item.inputReadOnly === true">
                      <van-field v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" :disabled="true" />
                    </template>
                    <template v-else>
                      <van-field v-model="data[item.dataIndex][index]" :style="`width:${item.inputWidth ? item.inputWidth : '100'}%`" />
                    </template>
                  </template>
                  <template v-else>
                    {{ activatedConfig.data[item.dataIndex][index] }}
                  </template>
                  <span class="inputsDivItemLabel">{{ displayFormatText(item.format, index) }}</span>
                </div>
              </div>
            </template>
          </div>
        </div>
        <!--      主体表格      -->
        <table v-if="render" class="reportTable" :style="activatedConfig.style ? activatedConfig.style : undefined">
          <tbody class="reportTable">
            <template v-for="(row, rowIndex) in activatedConfig.columns">
              <!--  插槽展示  -->
              <template v-if="row[0].type === 'slot'">
                <XReportTrGroup
                  :key="rowIndex"
                  :show-img-in-cell="showImgInCell"
                  :img-prefix="imgPrefix"
                  :server-name="serverName"
                  :env="env"
                  :use-oss-for-img="useOssForImg"
                  :columns="row"
                  :no-top-border="noTopBorder"
                  :config-data="activatedConfig.data"
                  :config="activatedConfig"
                  :display="true"
                  @update-img="updateImg"
                  @select-row="selectRow"
                  @slot-rendered="slotRendered"
                />
              </template>
              <!--  列表 list -->
              <template v-else-if="row[0].type === 'list'">
                <template v-for="(num, listIndex) in row[0].listLength + 1">
                  <template v-if="!forDisplay">
                    <XReportTrGroup
                      :key="`${rowIndex}-${listIndex}`"
                      :show-img-in-cell="showImgInCell"
                      :img-prefix="imgPrefix"
                      :server-name="serverName"
                      :env="env"
                      :use-oss-for-img="useOssForImg"
                      :config="activatedConfig"
                      :columns="row"
                      :no-top-border="noTopBorder"
                      :config-data="activatedConfig.data"
                      :list-index="listIndex"
                      @slot-rendered="slotRendered"
                      @update-img="updateImg"
                      @select-row="selectRow"
                    />
                  </template>
                  <template v-else>
                    <XReportTrGroup
                      :key="`${rowIndex}-${listIndex}`"
                      :show-img-in-cell="showImgInCell"
                      :img-prefix="imgPrefix"
                      :server-name="serverName"
                      :env="env"
                      :use-oss-for-img="useOssForImg"
                      :config="activatedConfig"
                      :columns="row"
                      :no-top-border="noTopBorder"
                      :config-data="activatedConfig.data"
                      :list-index="listIndex"
                      :display="true"
                      @slot-rendered="slotRendered"
                      @update-img="updateImg"
                      @select-row="selectRow"
                    />
                  </template>
                </template>
              </template>
              <!--  动态行 inputColumns -->
              <template v-else-if="row[0].type === 'inputColumns'">
                <template v-if="forDisplay">
                  <XReportTrGroup
                    v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
                    :key="row[0].dataIndex + definitionIndex + rowIndex"
                    :show-img-in-cell="showImgInCell"
                    :img-prefix="imgPrefix"
                    :server-name="serverName"
                    :env="env"
                    :use-oss-for-img="useOssForImg"
                    :config="activatedConfig"
                    :columns="row[0].definition"
                    :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
                    :input-columns="true"
                    :no-top-border="noTopBorder"
                    :input-columns-definition-index="definitionIndex"
                    :display="true"
                    @slot-rendered="slotRendered"
                    @update-img="updateImg"
                    @select-row="selectRow"
                  />
                </template>
                <template v-if="!forDisplay">
                  <XReportTrGroup
                    v-for="(item, definitionIndex) in activatedConfig.data[row[0].dataIndex]"
                    :key="row[0].dataIndex + definitionIndex + rowIndex"
                    :show-img-in-cell="showImgInCell"
                    :img-prefix="imgPrefix"
                    :server-name="serverName"
                    :env="env"
                    :use-oss-for-img="useOssForImg"
                    :config="activatedConfig"
                    :columns="row[0].definition"
                    :config-data="{ arr: activatedConfig.data[row[0].dataIndex] }"
                    :input-columns="true"
                    :no-top-border="noTopBorder"
                    :input-columns-definition-index="definitionIndex"
                    @slot-rendered="slotRendered"
                    @update-img="updateImg"
                    @select-row="selectRow"
                  />
                  <!--  动态行交互按钮  -->
                  <XReportTrGroup
                    :key="rowIndex"
                    :show-img-in-cell="showImgInCell"
                    :img-prefix="imgPrefix"
                    :server-name="serverName"
                    :env="env"
                    :use-oss-for-img="useOssForImg"
                    :config="activatedConfig"
                    :columns="row"
                    :no-top-border="noTopBorder"
                    :config-data="activatedConfig.data"
                    :input-columns-button="true"
                    :input-columns="true"
                    @slot-rendered="slotRendered"
                    @update-img="updateImg"
                    @select-row="selectRow"
                  />
                </template>
              </template>
              <!--  普通行  -->
              <template v-else>
                <template v-if="!forDisplay">
                  <XReportTrGroup
                    :key="rowIndex"
                    :show-img-in-cell="showImgInCell"
                    :img-prefix="imgPrefix"
                    :server-name="serverName"
                    :env="env"
                    :use-oss-for-img="useOssForImg"
                    :columns="row"
                    :no-top-border="noTopBorder"
                    :config-data="activatedConfig.data"
                    :config="activatedConfig"
                    @slot-rendered="slotRendered"
                    @update-img="updateImg"
                    @select-row="selectRow"
                  />
                </template>
                <template v-else>
                  <XReportTrGroup
                    :key="rowIndex"
                    :show-img-in-cell="showImgInCell"
                    :img-prefix="imgPrefix"
                    :server-name="serverName"
                    :env="env"
                    :use-oss-for-img="useOssForImg"
                    :config="activatedConfig"
                    :columns="row"
                    :no-top-border="noTopBorder"
                    :config-data="activatedConfig.data"
                    :display="true"
                    @slot-rendered="slotRendered"
                    @update-img="updateImg"
                    @select-row="selectRow"
                  />
                </template>
              </template>
            </template>
          </tbody>
        </table>
        <div v-if="showImages" style="margin-top: 5%; display: flex;margin-bottom: 5%">
          <p>图片：</p>
          <div v-for="(img, imgIndex) in imageList" :key="imgIndex" style="margin-left: 3%;width: 200px">
            <img :src="img.url" class="img" :alt="img.name">
            <p style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width: 100%;">
              {{ img.name }}
            </p>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<style lang="less" scoped>
.img {
  width: 95%;
  height: 180px;
  object-fit: cover;
}
.reportMain {
  text-align: center;
  margin: 0 auto;
  font-size: 16px;
  color: #000;
  background-color: #fff;
  border-radius: 8px;

  .reportTitle {
    font-weight: bold;
  }

  .subTitle {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1%;

    .subTitleItems {
      max-width: 30%;
    }
  }

  .inputsDiv {
    display: flex;
    justify-content: space-between;
    .inputsDivItem {
      display: flex;
      align-items: center;
      padding: 0 4px;
      white-space: nowrap;
      .inputsDivItemLabel {
        padding: 0 4px;
      }
    }
  }

  .reportTable {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    word-break: break-all;
  }
}
.reportMainForDisplay {
  text-align: center;
  margin: 10% auto;
  font-size: 16px;
  color: #000;
  background-color: #fff;
  border-radius: 8px;

  .reportTitle {
    font-weight: bold;
  }

  .subTitle {
    display: flex;
    justify-content: space-between;

    .subTitleItems {
      max-width: 30%;
    }
  }

  .inputsDiv {
    display: flex;
    justify-content: space-around;
    .inputsDivItem {
      display: flex;
      align-items: center;
      padding: 0 4px;
      white-space: nowrap;
      .inputsDivItemLabel {
        padding: 0 4px;
      }
    }
  }

  .reportTable {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    word-break: break-all;
  }
}
.reportMainNoPadding {
  // text-align: center;
  margin: 0 auto;
  font-size: 16px;
  color: #000;
  // background-color: #fff;
  border-radius: 8px;
  height: auto;
  min-height: 20vh;
  overflow-y: auto;
  overflow-x: hidden;

  .reportTitle {
    font-weight: bold;
  }

  .subTitle {
    display: flex;
    justify-content: space-between;

    .subTitleItems {
      max-width: 30%;
    }
  }

  .inputsDiv {
    display: flex;
    justify-content: space-between;
    .inputsDivItem {
      display: flex;
      align-items: center;
      padding: 0 4px;
      white-space: nowrap;
      .inputsDivItemLabel {
        padding: 0 4px;
      }
    }
  }

  .reportTable {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    word-break: break-all;
  }
}
.tools {
  position: fixed;
  right: 2%;
  text-align: right;
  width: 60%;
  cursor: pointer;
  .toolsItem {
    width: 15%;
    margin-right: 3%;
    display: inline-block;
  }
}
</style>
