<script>
import { getThumbnailUrl } from '@/api/asset'
import { AssetType } from '@/constant'

export default {
  name: 'SchemaTableColumn',
  inject: ['table'],
  props: {
    schema: {
      type: Object,
      required: true
    }
  },
  methods: {
    renderRefreshColumn (h, props) {
      const { render } = this.schema
      return h('el-table-column', {
        props: {
          width: 50,
          ...props
        },
        scopedSlots: {
          header: this.renderRefreshColumnHeader,
          default: render && function ({ store, row }) {
            return render(row, store.$createElement)
          }
        }
      })
    },
    renderRefreshColumnHeader () {
      return this.$createElement('i', {
        staticClass: 'o-refresh el-icon-refresh',
        on: { click: $event => {
          $event.stopPropagation()
          this.table.pageTo()
        } }
      })
    },
    renderExpandColumn (h, props) {
      const { render } = this.schema
      return h('el-table-column', {
        props: {
          type: 'expand',
          ...props
        },
        scopedSlots: {
          default ({ store, row }) {
            return render(row, store.$createElement)
          }
        }
      })
    },
    renderAssetColumn (h, props) {
      return h('el-table-column', {
        props: {
          'class-name': 'c-thumbnail-col',
          label: '文件',
          align: 'center',
          width: 100,
          ...props
        },
        scopedSlots: {
          default: this.renderAsset
        }
      })
    },
    renderAsset ({ row: data }) {
      const value = this.getRenderValue(data)
      if (value) {
        const { on } = this.schema
        if (value.thumbnail) {
          return this.$createElement('auto-image', {
            staticClass: `o-thumbnail${on ? ' u-pointer' : ''}`,
            props: {
              src: getThumbnailUrl(value.thumbnail, '64,fit'),
              broken: value.type === AssetType.VIDEO ? 'video-broken' : 'image-broken'
            },
            nativeOn: on && { click: $event => {
              $event.stopPropagation()
              on(value, data)
            } }
          })
        }
        switch (value.type) {
          case AssetType.VIDEO:
          case AssetType.AUDIO:
            return this.$createElement('SvgIcon', {
              staticClass: `o-thumbnail${on ? ' u-pointer' : ''}`,
              props: {
                'icon-class': value.type === AssetType.VIDEO
                  ? value.thumbnail === ''
                    ? 'video-broken'
                    : 'video-thumb'
                  : 'audio-thumb'
              },
              on: on && { click: $event => {
                $event.stopPropagation()
                on(value, data)
              } }
            })
          default:
            break
        }
      }
      return '-'
    },
    renderChildren (data) {
      const { type, render } = this.schema
      let children = null
      switch (type) {
        case 'tag':
          children = this.renderTags(data.row)
          break
        case 'invoke':
          children = this.renderInvokes(data)
          break
        default:
          children = render && render(data.row, this.$createElement)
          break
      }
      if (children && !Array.isArray(children)) {
        children = [children]
      }
      return children && children.length ? children : null
    },
    getRenderValue (data) {
      const { prop, render } = this.schema
      return render ? render(data) : data[prop]
    },
    renderTags (data) {
      const tags = this.getRenderValue(data)
      if (tags) {
        if (Array.isArray(tags)) {
          if (tags.length > 1) {
            return this.$createElement('div', {
              staticClass: 'c-tags'
            }, tags.map(tag => this.renderTag(tag, data)))
          }
          return tags.map(tag => this.renderTag(tag, data))
        }
        return this.renderTag(tags, data)
      }
      return '-'
    },
    renderTag (tag, data) {
      if (!tag) {
        return '-'
      }
      const { msg } = tag
      if (msg) {
        return this.$createElement('el-tooltip', {
          props: {
            content: msg,
            placement: 'left',
            enterable: false
          }
        }, [
          this.createTag(tag, data)
        ])
      }
      return this.createTag(tag, data)
    },
    createTag (tag, data) {
      const { label, ...tagProps } = tag
      const { on } = this.schema
      return this.$createElement('el-tag', {
        staticClass: on ? 'o-tag u-pointer' : 'o-tag u-readonly',
        props: {
          size: 'medium',
          ...tagProps
        },
        on: on && { click: $event => {
          $event.stopPropagation()
          on(data, tag)
        } }
      }, label)
    },
    renderInvokes (data) {
      const { render, use } = this.schema
      const h = this.$createElement
      if (!use || use(data.row)) {
        return (Array.isArray(render) ? render : render(data.row))
          .filter(({ render }) => !render || render(data.row))
          .map(({ label, on }) => h('div', {
            staticClass: 'c-table__btn u-pointer',
            on: on && {
              click ($event) {
                $event.stopPropagation()
                on(data.row, data.$index)
              }
            }
          }, label))
      }
      return null
    }
  },
  render (h) {
    const { type, render, ...columnProps } = this.schema

    let defaultProps = null
    switch (type) {
      case 'refresh':
        return this.renderRefreshColumn(h, columnProps)
      case 'expand':
        return this.renderExpandColumn(h, columnProps)
      case 'asset':
        return this.renderAssetColumn(h, columnProps)
      case 'selection':
        return h('el-table-column', {
          props: {
            type,
            width: 50
          }
        })
      case 'tag':
        defaultProps = { label: '状态' }
        break
      case 'invoke':
        defaultProps = { label: '操作', align: render?.length > 1 ? 'right' : 'center', width: 120 }
        break
      default:
        defaultProps = { 'show-overflow-tooltip': true }
        break
    }

    return h('el-table-column', {
      props: {
        ...defaultProps,
        ...columnProps
      },
      scopedSlots: {
        default: type || render ? this.renderChildren : null
      }
    })
  }
}
</script>
