<template>
  <div>
    <vxe-toolbar
      custom
      ref="xToolbar"
      :loading="apiData.loading"
      :refresh="{query: loadList}">
      <template #buttons>
        <vxe-input clearable class="search-input" v-model="apiData.filterName" type="search" :placeholder="`vxe-${apiName} ${$t('app.api.apiSearch')}`" @keyup="searchEvent" @clear="searchEvent"></vxe-input>
      </template>
    </vxe-toolbar>

    <vxe-table
      resizable
      auto-resize
      show-header-overflow
      highlight-current-row
      highlight-hover-row
      highlight-current-column
      ref="xTable"
      id="document_api"
      class="api-table"
      row-id="id"
      :loading="apiData.loading"
      :cell-class-name="cellClassNameFunc"
      :data="apiData.apiList"
      :custom-config="{storage: true, checkMethod: checkColumnMethod}"
      :tree-config="{children: 'list', expandRowKeys: apiData.defaultExpandRowKeys}"
      :menu-config="{header: {options: apiData.headerMenus}, body: {options: apiData.bodyMenus}, visibleMethod: menuVisibleMethod}"
      :tooltip-config="{contentMethod: showTooltipMethod}"
      @header-cell-menu="headerCellContextMenuEvent"
      @cell-menu="cellContextMenuEvent"
      @menu-click="contextMenuClickEvent">
      <vxe-table-column field="name" title="app.api.title.prop" type="html" min-width="280" show-overflow :title-help="{message: '参数名称及使用，如果是在 CDN 环境中使用 kebab-case（短横线式），如果项目基于 vue-cli 脚手架可以使用 camelCase（驼峰式）'}" :filters="apiData.nameFilters" tree-node></vxe-table-column>
      <vxe-table-column field="desc" title="app.api.title.desc" type="html" min-width="200"></vxe-table-column>
      <vxe-table-column field="type" title="app.api.title.type" type="html" min-width="140"></vxe-table-column>
      <vxe-table-column field="enum" :title="$t('app.api.title.enum')" type="html" min-width="150"></vxe-table-column>
      <vxe-table-column field="defVal" :title="$t('app.api.title.defVal')" type="html" min-width="160" :title-help="{message: '部分参数可支持全局设置，具体请查阅相关说明'}"></vxe-table-column>
      <vxe-table-column field="version" :title="$t('app.api.title.version')" width="120" :title-help="{message: '该文档与最新版本保持同步，如果遇到参数无效时，需要检查当前使用的版本号是否支持该参数'}">
        <template #default="{ row }">
          <template v-if="row.version === 'pro'">
            <a class="link pro" href="https://xuliangzhan_admin.gitee.io/vxe-table/plugins/#/pro" target="_blank">pro</a>
          </template>
           <template v-else-if="row.disabled">
            <span class="disabled">已废弃</span>
          </template>
           <template v-else-if="row.abandoned">
            <span class="abandoned">评估阶段</span>
          </template>
          <template v-else>
            <span v-show="row.version" class="compatibility">v{{  row.version }}</span>
          </template>
        </template>
      </vxe-table-column>
      <template #empty>
        <span class="red">找不对应 API，请输入正确的关键字！</span>
      </template>
    </vxe-table>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, nextTick, reactive, watch, ref } from 'vue'
import { RouteLocationNormalized, NavigationGuardNext } from 'vue-router'
import { VXETable } from '../../../packages/vxe-table'
import i18n from '@/i18n'
import router from '@/router'
import XEUtils from 'xe-utils'
import pack from '../../../package.json'

import { VxeTableInstance, VxeToolbarInstance } from '../../../types/vxe-table'

import XEClipboard from 'xe-clipboard'
import tableAPI from '../../api/table'
import tableColgroupAPI from '../../api/table-colgroup'
import tableColumnAPI from '../../api/column'
import toolbarAPI from '../../api/toolbar'
import gridAPI from '../../api/grid'
import virtualTreeAPI from '../../api/virtual-tree'
import pagerAPI from '../../api/pager'
import radioAPI from '../../api/radio'
import radioGroupAPI from '../../api/radio-group'
import radioButtonAPI from '../../api/radio-button'
import checkboxAPI from '../../api/checkbox'
import checkboxGroupAPI from '../../api/checkbox-group'
import inputAPI from '../../api/input'
import selectAPI from '../../api/select'
import optgroupAPI from '../../api/optgroup'
import optionAPI from '../../api/option'
import textareaAPI from '../../api/textarea'
import buttonAPI from '../../api/button'
import tooltipAPI from '../../api/tooltip'
import modalAPI from '../../api/modal'
import formAPI from '../../api/form'
import formItemAPI from '../../api/form-item'
import switchAPI from '../../api/switch'
import listAPI from '../../api/list'
import pulldownAPI from '../../api/pulldown'

// declare global {
//   interface Window {
//     attributes: any;
//     tags: any;
//   }
// }

// const attributes: any = window.attributes = {}
// const tags: any = window.tags = {}

// const tagMaps = [
//   ['vxe-table', tableAPI, { subtags: ['vxe-table-column'], description: '基础表格' }],
//   ['vxe-table-colgroup', tableColgroupAPI, { description: '基础表格 - 分组列' }],
//   ['vxe-table-column', tableColumnAPI, { description: '基础表格 - 列' }],
//   ['vxe-grid', gridAPI, { description: '高级表格' }],
//   ['vxe-toolbar', toolbarAPI, { description: '工具栏' }],
//   ['vxe-pager', pagerAPI, { description: '分页' }],
//   ['vxe-radio', radioAPI, { description: '单选框' }],
//   ['vxe-radio-group', radioGroupAPI, { description: '单选组' }],
//   ['vxe-radio-button', radioButtonAPI, { description: '单选按钮' }],
//   ['vxe-checkbox', checkboxAPI, { description: '复选框' }],
//   ['vxe-checkbox-group', checkboxGroupAPI, { description: '复选组' }],
//   ['vxe-switch', switchAPI, { description: '开关按钮' }],
//   ['vxe-input', inputAPI, { description: '输入框' }],
//   ['vxe-select', selectAPI, { subtags: ['vxe-optgroup', 'vxe-option'], description: '下拉框' }],
//   ['vxe-optgroup', optgroupAPI, { subtags: ['vxe-option'], description: '下拉框 - 分组' }],
//   ['vxe-option', optionAPI, { description: '下拉框 - 选项' }],
//   ['vxe-button', buttonAPI, { description: '按钮' }],
//   ['vxe-tooltip', tooltipAPI, { description: '工具提示' }],
//   ['vxe-modal', modalAPI, { description: '模态窗口' }],
//   ['vxe-form', formAPI, { subtags: ['vxe-form-item'], description: '表单' }],
//   ['vxe-form-item', formItemAPI, { description: '表单 - 项' }],
//   ['vxe-list', listAPI, { description: '列表' }],
//   ['vxe-pulldown', pulldownAPI, { description: '下拉容器' }]
// ]

// tagMaps.forEach(confs => {
//   const props = confs[1].find((item: any) => item.name === 'Props').list
//   const keys: any[] = []
//   props.forEach((item: any) => {
//     const name = XEUtils.kebabCase(item.name)
//     attributes[`${confs[0]}/${name}`] = {
//       type: XEUtils.toString(item.type).toLowerCase(),
//       description: item.descKey ? i18n.global.t(item.descKey) : item.desc
//     }
//     keys.push(name)
//   })
//   tags[confs[0]] = Object.assign({ attributes: keys }, confs[2])
// })

export default defineComponent({
  setup () {
    const q = (router.currentRoute.value.query.q || router.currentRoute.value.query.filterName) as string
    const apiData = reactive({
      filterName: q ? decodeURIComponent(q) : '',
      apiList: [] as any[],
      defaultExpandRows: [] as string[],
      defaultExpandRowKeys: [] as string[],
      loading: false,
      tableData: [] as any[],
      nameFilters: [
        { label: 'Props', value: 'Props' },
        { label: 'Slots', value: 'Slots' },
        { label: 'Events', value: 'Events' },
        { label: 'Methods', value: 'Methods' }
      ],
      headerMenus: [
        [
          {
            code: 'hideColumn',
            name: '隐藏列',
            disabled: false
          },
          {
            code: 'showAllColumn',
            name: '取消所有隐藏列'
          },
          {
            code: 'resetColumn',
            name: '重置个性化数据'
          }
        ],
        [
          {
            code: 'exportXLSXAPI',
            name: '导出文档.xlsx',
            prefixIcon: 'fa fa-download'
          }
        ]
      ],
      bodyMenus: [
        [
          {
            code: 'copy',
            name: 'app.body.label.copy',
            prefixIcon: 'fa fa-copy'
          }
        ],
        [
          {
            code: 'resize',
            name: '重新加载'
          },
          {
            code: 'exportHTMLAPI',
            name: '导出文档.html',
            prefixIcon: 'fa fa-download'
          },
          {
            code: 'exportXLSXAPI',
            name: '导出文档.xlsx',
            prefixIcon: 'fa fa-download'
          }
        ],
        [
          {
            code: 'allExpand',
            name: '全部展开'
          },
          {
            code: 'allShrink',
            name: '全部收起'
          }
        ]
      ]
    })

    const xTable = ref({} as VxeTableInstance)
    const xToolbar = ref({} as VxeToolbarInstance)

    const apiName = computed(() => {
      const $route = router.currentRoute.value
      return $route.params.name
    })

    const cellClassNameFunc = ({ row, column }: any) => {
      return {
        'api-pro': row.version === 'pro',
        'api-disabled': row.disabled,
        'api-abandoned': row.abandoned,
        'disabled-line-through': (row.disabled) && column.property === 'name'
      }
    }

    const checkColumnMethod = ({ column }: any) => {
      if (['name', 'desc'].includes(column.property)) {
        return false
      }
      return true
    }

    const showTooltipMethod = ({ type, row, column }: any) => {
      if (type === 'body') {
        if (column.property === 'name') {
          if (row.disabled) {
            return '该参数已经被废弃了，除非不打算更新版本，否则不应该被使用'
          } else if (row.abandoned) {
            return '该参数属于评估阶段，谨慎使用，后续有可能会被废弃的风险'
          } else if (row.version === 'pro') {
            return '该参数属于 pro 版本功能，需获取授权，如有需要可联系邮件：xu_liangzhan@163.com'
          }
        }
      }
      return null
    }

    const headerCellContextMenuEvent = ({ column }: any) => {
      const $table = xTable.value
      $table.setCurrentColumn(column)
    }

    const cellContextMenuEvent = ({ row }: any) => {
      const $table = xTable.value
      $table.setCurrentRow(row)
    }

    const handleSearch = () => {
      const filterName = XEUtils.toString(apiData.filterName).trim()
      if (filterName) {
        const options = { children: 'list' }
        if (/pro/i.test(filterName)) {
          const rest = XEUtils.searchTree(apiData.tableData, item => item.version === 'pro', options)
          apiData.apiList = rest
        } else {
          const filterRE = new RegExp(`${filterName}|${XEUtils.camelCase(filterName)}|${XEUtils.kebabCase(filterName)}`, 'i')
          const searchProps = ['name', 'desc', 'type', 'enum', 'defVal', 'version']
          const rest = XEUtils.searchTree(apiData.tableData, item => searchProps.some(key => filterRE.test(item[key])), options)
          XEUtils.eachTree(rest, item => {
            searchProps.forEach(key => {
              if (key !== 'version') {
                item[key] = item[key].replace(filterRE, (match: string) => `<span class="keyword-lighten">${match}</span>`)
              }
            })
          }, options)
          apiData.apiList = rest
        }
        setTimeout(() => {
          const $table = xTable.value
          if ($table) {
            $table.setAllTreeExpand(true)
          }
        }, 300)
      } else {
        apiData.apiList = apiData.tableData
        nextTick(() => {
          const $table = xTable.value
          if ($table) {
            $table.setTreeExpand(apiData.defaultExpandRows, true)
          }
        })
      }
    }

    // 调用频率间隔 500 毫秒
    const searchEvent = XEUtils.debounce(handleSearch, 500, { leading: false, trailing: true })

    const loadList = () => {
      const $route = router.currentRoute.value
      apiData.loading = true
      return new Promise(resolve => {
        setTimeout(() => {
          let apis: any[] = []
          switch ($route.params.name) {
            case 'table':
              apis = tableAPI
              break
            case 'table-colgroup':
              apis = tableColgroupAPI
              break
            case 'table-column':
              apis = tableColumnAPI
              break
            case 'toolbar':
              apis = toolbarAPI
              break
            case 'grid':
              apis = gridAPI
              break
            case 'virtual-tree':
              apis = virtualTreeAPI
              break
            case 'pager':
              apis = pagerAPI
              break
            case 'radio':
              apis = radioAPI
              break
            case 'radio-group':
              apis = radioGroupAPI
              break
            case 'radio-button':
              apis = radioButtonAPI
              break
            case 'checkbox':
              apis = checkboxAPI
              break
            case 'checkbox-group':
              apis = checkboxGroupAPI
              break
            case 'input':
              apis = inputAPI
              break
            case 'textarea':
              apis = textareaAPI
              break
            case 'select':
              apis = selectAPI
              break
            case 'optgroup':
              apis = optgroupAPI
              break
            case 'option':
              apis = optionAPI
              break
            case 'button':
              apis = buttonAPI
              break
            case 'tooltip':
              apis = tooltipAPI
              break
            case 'modal':
              apis = modalAPI
              break
            case 'form':
              apis = formAPI
              break
            case 'form-item':
              apis = formItemAPI
              break
            case 'switch':
              apis = switchAPI
              break
            case 'list':
              apis = listAPI
              break
            case 'pulldown':
              apis = pulldownAPI
              break
          }
          // 生成唯一 id
          let index = 1
          const searchProps = ['name', 'desc', 'type', 'enum', 'defVal']
          apiData.tableData = XEUtils.clone(apis, true)
          XEUtils.eachTree(apiData.tableData, (item: any) => {
            item.id = index++
            item.desc = item.descKey ? i18n.global.t(item.descKey) : item.desc
            searchProps.forEach(key => {
              item[key] = XEUtils.escape(item[key])
            })
          }, { children: 'list' })
          // 默认展开一级
          apiData.defaultExpandRows = apiData.tableData.filter((item: any) => item.list && item.list.length)
          apiData.defaultExpandRowKeys = apiData.defaultExpandRows.map((item: any) => item.id)
          apiData.loading = false
          handleSearch()
          resolve()
        }, 100)
      })
    }

    const contextMenuClickEvent = ({ menu, row, column }: any) => {
      const $table = xTable.value
      switch (menu.code) {
        case 'hideColumn':
          $table.hideColumn(column)
          break
        case 'showAllColumn':
          $table.resetColumn({ visible: true })
          break
        case 'resetColumn':
          $table.resetColumn(true)
          break
        case 'exportHTMLAPI':
          $table.exportData({
            type: 'html',
            data: XEUtils.toTreeArray(apiData.tableData, { children: 'list' }),
            filename: `vxe-${apiName.value}_v${pack.version}`
          })
          break
        case 'exportXLSXAPI':
          $table.exportData({
            type: 'xlsx',
            data: XEUtils.toTreeArray(apiData.tableData, { children: 'list' }),
            filename: `vxe-${apiName.value}_v${pack.version}`
          })
          break
        case 'copy':
          if (row && column) {
            if (XEClipboard.copy(row[column.property])) {
              VXETable.modal.message({ message: i18n.global.t('app.body.msg.copyToClipboard'), status: 'success' })
            }
          }
          break
        case 'resize':
          apiData.filterName = ''
          apiData.tableData = []
          nextTick(() => {
            $table.clearAll()
            loadList()
          })
          break
        case 'exportAPI':
          $table.exportData({
            filename: `vxe-${apiName.value}_v${pack.version}.csv`
          })
          break
        case 'allExpand':
          $table.setAllTreeExpand(true)
          break
        case 'allShrink':
          $table.clearTreeExpand()
          break
      }
    }

    const menuVisibleMethod = ({ options, column }: any) => {
      const isDisabled = !checkColumnMethod({ column })
      options.forEach((list: any) => {
        list.forEach((item: any) => {
          if (['hideColumn'].includes(item.code)) {
            item.disabled = isDisabled
          }
        })
      })
      return true
    }

    watch(apiName, () => {
      loadList()
    })

    watch(() => i18n.global.locale, () => {
      loadList()
    })

    nextTick(() => {
      // 将表格和工具栏进行关联
      const $table = xTable.value
      const $toolbar = xToolbar.value
      $table.connect($toolbar)
      loadList()
    })

    return {
      xTable,
      xToolbar,
      apiData,
      apiName,

      loadList,
      cellClassNameFunc,
      checkColumnMethod,
      showTooltipMethod,
      headerCellContextMenuEvent,
      cellContextMenuEvent,
      contextMenuClickEvent,
      menuVisibleMethod,
      searchEvent,
      handleSearch
    }
  },
  beforeRouteUpdate (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) {
    next()
    this.apiData.filterName = ''
    const xTable: any = this.$refs.xTable
    if (xTable) {
      xTable.clearAll()
    }
    this.handleSearch()
  }
})
</script>
