<template>
  <div class="split" ref="parent">
    <slot></slot>
  </div>
</template>

<script lang="ts">
//@ts-ignore
import Split from 'split.js'
import { defineComponent, onMounted, ref, type SetupContext, type VNode, watch } from 'vue'

interface IDataContainer {
  instance: any;
  elements: Array<any> | undefined;
  sizes: Array<number> | undefined;
  minSizes: Array<number> | undefined;
  destroy: Function,
}

//@ts-ignore
export default defineComponent({
  emits: ['onDrag', 'onDragStart', 'onDragEnd'],
  props: {
    direction: { type: String, default: 'horizontal' }, // vertical
    gutterSize: { type: Number, default: 8 },
    firstAreaDefaultSize: Number,
    lastAreaDefaultSize: Number
  },

  setup(props, ctx: SetupContext) {
    const parent = ref(null)
    const dataVal = {
      elements: new Array<any>(),
      sizes: new Array<number>(),
      minSizes: new Array<number>(),
      instance: null,
      //@ts-ignore
      destory: Function
    }

    //@ts-ignore
    const data = ref(dataVal as IDataContainer)
    watch(() => props.direction, (value, oldValue) => {
      init()
    })
    let useFirstDefaultSize = props.firstAreaDefaultSize && props.firstAreaDefaultSize > 0
    let useLastDefaultSize = props.lastAreaDefaultSize && props.lastAreaDefaultSize > 0
    let splitSumCount = 0
    const refreshSize = (value) => {
      if (data.value.instance) {
        data.value.instance?.setSizes(value)
      }
    }
    const init = () => {
      if (data.value.instance !== null) {
        data.value.instance?.destroy()
      }
      let splitCount = 0
      data.value.instance = null
      const splitOptions = {
        direction: props.direction || 'horizontal',
        sizes: data.value.sizes || 50,
        minSize: data.value.minSizes || 100,
        gutterSize: props.gutterSize || 8,
        cursor: props.direction === 'horizontal' ? 'col-resize' : 'row-resize',
        onDrag: function() {
          useFirstDefaultSize = false
          useLastDefaultSize = false
          ctx.emit('onDrag', data.value.instance?.getSizes())
        },
        onDragStart: function() {
          ctx.emit('onDragStart', data.value.instance?.getSizes())
        },
        onDragEnd: function() {
          ctx.emit('onDragEnd', data.value.instance?.getSizes())
        }
      }
      if (useFirstDefaultSize) {
        splitOptions['elementStyle'] = function elementStyle(dimension, size, gutterSize) {
          splitCount++
          let res
          if (splitSumCount === 2 && useFirstDefaultSize && !useLastDefaultSize) {
            // 2个split-area & 使用firstAreaDefaultSize & 未使用lastAreaDefaultSize
            if (splitCount === 1) {
              res = { [dimension]: `calc(${props.firstAreaDefaultSize}px - ${gutterSize}px)` }
            } else {
              res = { [dimension]: `calc(100% - ${props.firstAreaDefaultSize + gutterSize}px)` }
            }
          } else if (splitSumCount === 2 && !useFirstDefaultSize && useLastDefaultSize) {
            // 2个split-area & 未使用firstAreaDefaultSize & 使用了lastAreaDefaultSize
            if (splitCount === 2) {
              res = { [dimension]: `calc(${props.lastAreaDefaultSize}px - ${gutterSize}px)` }
            } else {
              res = { [dimension]: `calc(100% - ${props.lastAreaDefaultSize + gutterSize}px)` }
            }
          } else if (splitSumCount === 3 && useFirstDefaultSize && useLastDefaultSize) {
            // 3个split-area & 使用firstAreaDefaultSize & 使用了lastAreaDefaultSize
            if (splitCount === 1) {
              res = { [dimension]: `calc(${props.firstAreaDefaultSize}px - ${gutterSize}px)` }
            } else if (splitCount === 3) {
              res = { [dimension]: `calc(${props.lastAreaDefaultSize}px - ${gutterSize}px)` }
            } else {
              res = { [dimension]: `calc(100% - ${props.firstAreaDefaultSize + props.lastAreaDefaultSize + gutterSize}px)` }
            }
          } else {
            res = { [dimension]: `calc(${size}% - ${gutterSize}px)` }
          }
          return res
        }
      }
      //@ts-ignore
      data.value.instance = Split(data.value.elements ?? [],
        splitOptions as Split.Options
      )
    }
    onMounted(() => {
      data.value.elements = []
      data.value.sizes = []
      data.value.minSizes = []
      var parentVal = parent.value as unknown as HTMLElement

      if (parentVal) {
        for (var i = 0; i < parentVal.children.length; i++) {
          var child = parentVal.children[i]
          data.value.elements.push(child)
        }
      }
      if (ctx.slots.default) {
        ctx.slots.default()?.forEach((vnode: VNode) => {
          const vodeType = vnode.type as any
          if (vodeType.name == 'SplitArea') {
            if (vnode.props) {
              const a = vnode.props as {
                size: number;
                minSize: number;
              }
              data.value.sizes?.push(a.size)
              data.value.minSizes?.push(a.minSize)
            }
          }
        })
        splitSumCount = ctx.slots.default().length
      }
      init()
    })

    const reset = () => {
      useFirstDefaultSize = props.firstAreaDefaultSize && props.firstAreaDefaultSize > 0
      useLastDefaultSize = props.lastAreaDefaultSize && props.lastAreaDefaultSize > 0
      init()
    }
    const getSizes = () => {
      return data.value.instance?.getSizes() || 0
    }

    return { data, init, parent, reset, getSizes, refreshSize }
  }
})
</script>

<style>
.split {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  overflow-y: auto;
  overflow-x: hidden;
  height: 100%;
  width: 100%;
}

.gutter {
  background-color: #eee;
  background-repeat: no-repeat;
  background-position: 50%;
}

.gutter.gutter-horizontal {
  cursor: col-resize;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==");
}

.gutter.gutter-vertical {
  cursor: row-resize;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=");
}

.split.split-horizontal,
.gutter.gutter-horizontal {
  height: 100%;
  float: left;
}
</style>