import { createVNode, ref, render, VNode } from 'vue'
import { ElButton } from 'element-plus'
import StepLoadingItem from './components/step-loading-item'

interface IOption {
  request: <T>() => Promise<T>
  name: string
}

export default function (options: Array<IOption> = []) {
  let vm: VNode = null
  const parent = document.body
  const LoadingComponent = {
    name: 'SkStepLoading',
    setup() {
      const arr: Array<'success' | 'error' | 'loading'> = new Array(options.length).fill('loading')
      const statusArr = ref(arr)

      function destroySelf (e) {
        if (e.target === e.currentTarget && statusArr.value.includes('error') || e === '') {
          if (vm.el && vm.el.parentNode) {
            vm.el.parentNode.removeChild(vm.el)
          }
        }
      }

      async function run () {
        for (const [index, item] of options.entries()) {
          try {
            const res = await item.request()
            if (res) statusArr.value[index] = 'success'
            else{
              statusArr.value.fill('error', index, options.length)
              return
            }
          } catch (e) {
            statusArr.value.fill('error', index, options.length)
            return
          }
        }
        destroySelf('')
      }

      const reRun = () => {
        statusArr.value = new Array(options.length).fill('loading')
        run()
      }

      run()
      return () => (
        <div class='sk-step-loading sk-flex sk-center' onClick={e => {destroySelf(e)}}>
          <div class='step-loading-x sk-flex sk-column'>
            {
              options.map((item, index) => {
                return (
                  <StepLoadingItem
                    name={item.name}
                    status={statusArr.value[index]}
                    showline={index !== options.length - 1}
                  />
                ) as any
              })
            }
            {
              statusArr.value.includes('error') &&
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              <ElButton size='small' type='primary' onClick={reRun}>重试</ElButton>
            }
          </div>
        </div>
      )
    },
  }
  vm = createVNode(LoadingComponent)
  render(vm, document.createElement('div'))
  parent.appendChild(vm.el as HTMLElement)
}
