<script>
import {
  getAssetUrl,
  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: 48,
          align: 'center',
          ...props
        },
        scopedSlots: {
          header: this.renderRefreshColumnHeader,
          default: render && function ({ store, row }) {
            return render(row, store.$createElement)
          }
        }
      })
    },
    renderRefreshColumnHeader () {
      return this.$createElement('i', {
        staticClass: 'el-icon-refresh u-color--black light u-font-size--xl u-vertical--middle has-active',
        on: { click: $event => {
          $event.stopPropagation()
          this.table.pageTo()
        } }
      })
    },
    renderExpandColumn (h, props) {
      const { refresh, render } = this.schema
      return h('el-table-column', {
        props: {
          type: 'expand',
          ...props
        },
        scopedSlots: {
          header: refresh ? this.renderRefreshColumnHeader : null,
          default ({ store, row }) {
            return render(row, store.$createElement)
          }
        }
      })
    },
    renderAssetColumn (h, { refresh, ...props }) {
      return h('el-table-column', {
        props: {
          'class-name': 'c-thumbnail-column',
          label: '资源',
          align: 'center',
          width: 100,
          ...props
        },
        scopedSlots: {
          header: refresh ? this.renderRefreshColumnHeader : null,
          default: this.renderAsset
        }
      })
    },
    renderAsset ({ row: data }) {
      const value = this.getRenderValue(data)
      if (!value) {
        return this.$createElement('div', {
          staticClass: 'o-thumbnail u-font-size--sm'
        }, data.draft || '-')
      }
      const { on } = this.schema
      const thumb = value.thumb || (value.type === AssetType.IMAGE ? value.url : null)
      if (thumb) {
        return this.$createElement('auto-image', {
          staticClass: `o-thumbnail u-font-size--lg u-color--blue ${on ? 'u-pointer' : ''}`,
          props: {
            src: value.net
              ? thumb
              : value.origin
                ? getAssetUrl(thumb)
                : getThumbnailUrl(thumb, '80,fit'),
            broken: 'image-broken'
          },
          nativeOn: on && { click: $event => {
            $event.stopPropagation()
            on(data, value)
          } }
        })
      }
      let svgIcon = null
      switch (value.type) {
        case AssetType.AUDIO:
          svgIcon = 'audio-thumb'
          break
        default:
          svgIcon = 'video-thumb'
          break
      }
      return this.$createElement('SvgIcon', {
        staticClass: `o-thumbnail ${on ? 'u-pointer' : ''}`,
        props: { 'icon-class': svgIcon },
        on: on && { click: $event => {
          $event.stopPropagation()
          on(data, value)
        } }
      })
    },
    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 this.$createElement('span', {
          staticClass: 'o-tag u-readonly',
          staticStyle: { display: 'inline-block' }
        }, '-')
      }
      if (!tag.type) {
        return this.$createElement('span', {
          staticClass: 'o-tag u-readonly',
          staticStyle: { display: 'inline-block' }
        }, tag.label)
      }
      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, ignore, size = '', ...tagProps } = tag
      const { on } = this.schema
      return this.$createElement('el-tag', {
        staticClass: on && !ignore ? `o-tag ${size} u-pointer` : `o-tag ${size} u-readonly`,
        props: {
          size: 'medium',
          'disable-transitions': true,
          ...tagProps
        },
        on: on && !ignore && { 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, allow, on }) => {
            const allowed = allow ? allow(data.row) : true
            return h('div', {
              staticClass: allowed ? 'c-table__btn' : 'c-table__btn disabled',
              on: allowed && on && {
                click ($event) {
                  $event.stopPropagation()
                  on(data.row, data.$index)
                }
              }
            }, label
              ? typeof label === 'string'
                ? label
                : label(data.row)
              : '操作')
          })
      }
      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: 42,
            ...columnProps
          }
        })
      case 'tag':
        defaultProps = {
          label: '状态',
          width: 100,
          align: 'center'
        }
        break
      case 'invoke':
        defaultProps = {
          label: '操作',
          width: render?.length > 1 ? 120 : 80,
          align: render?.length > 1 ? 'right' : 'center'
        }
        break
      default:
        defaultProps = { 'show-overflow-tooltip': true }
        break
    }

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