<template>
  <view class="m-tabbar-box" :style="tabbarBoxStyle" v-if="isShowTabBar">
    <view class="m-tabbar__fill" v-if="fill || native" :class="{'m-tabbar__safe': (safeBottom || native)}"
      :style="tabbarFillStyle"></view>
    <view id="m-tabbar" class="m-tabbar" :class="{'fixed': (fixed || native), 'm-tabbar__safe': (safeBottom || native)}"
      :style="tabbarStyle">
      <view class="m-tabbar__border" v-if="borderStyle === 'black' "></view>
      <view class="m-tabbar__flex">
        <view @click="tabChange(index)" v-for="(item, index) in tabbarList" :key="index" class="m-tabbar__item" :class="{
						'm-tabbar__item__active': index === currentIndex,
					}">
          <slot :name="`tabbar_index_${index}`">
            <view class="m-tabbar__icon">
              <view class="m-tabbar__badge" v-if="item.dot">{{item.dot}}</view>
              <image :src="currentIndex === index ? item.selectedIconPath : item.iconPath" class="m-tabbar__icon_img" />
            </view>
            <view class="m-tabbar__label"
              :style="{'color': index === currentIndex ? tabbarConfig.selectedColor : tabbarConfig.color }">
              {{ item.text }}
            </view>
          </slot>
        </view>
      </view>
      <view :style="{ paddingBottom: systemInfo.tabbarPaddingB + 'px', background: '#fff' }"></view>
    </view>
  </view>
</template>

<script>
  const obj2strStyle = (obj) => {
    let style = ''
    for (let key in obj) {
      style += `${key}:${obj[key]};`
    }
    return style
  }

  const padFirstSymbol = (str, smb) => {
    if (str.startsWith(smb) || str.startsWith('http')) {
      return str
    }
    return `/${str}`
  }

  const replaceTabbarList = (list) => {
    if (!list.length > 0) {
      return []
    }
    return list.map(item => {
      if (item.iconPath) {
        item.iconPath = padFirstSymbol(item.iconPath, '/')
      }
      if (item.pagePath) {
        item.pagePath = padFirstSymbol(item.pagePath, '/')
      }
      if (item.selectedIconPath) {
        item.selectedIconPath = padFirstSymbol(item.selectedIconPath, '/')
      }
      return item
    })
  }
  // import base from '@/config/baseUrl.js';
  import PageConfig from '@/pages.json'
  export default {
    emits: ['change', 'click'],
    props: {
      current: {
        type: [Number, String],
        default: 0
      },
      tabbar: {
        type: Object,
        default () {
          return {}
        }
      },
      fixed: {
        type: Boolean,
        default: false
      },
      fill: {
        type: Boolean,
        default: false
      },
      zIndex: {
        type: [Number, String],
        default: 9999
      },
      native: {
        type: Boolean,
        default: false
      },
      safeBottom: {
        type: Boolean,
        default: true
      },
      beforeChange: {
        type: Function,
        default: null
      },
      tabbarHeight: {
        type: [Number, String],
        default: 100
      }
    },
    data() {
      return {
        systemInfo: {},
        isShowTabBar: false,
        currentIndex: 0,
        beforeData: {},
        reload: false
      }
    },
    watch: {
      current(val) {
        this.currentIndex = val * 1
      }
    },
    computed: {
      tabbarConfig() {
        const {
          native,
          reload
        } = this
        if (reload) {}
        if (native) {
          const {
            tabBar
          } = PageConfig
          if (!tabBar) {
            console.error('Native mode, Pages.json no tabbar config')
            return {
              borderStyle: 'black',
              list: []
            }
          }
          return tabBar
        }
        return this.tabbar
      },
      tabbarList() {
        const {
          reload
        } = this
        const {
          list
        } = this.tabbarConfig
        if (reload) {}
        if (list) {
          return replaceTabbarList(list)
        }
        console.error('No tabbar config')
        return []
      },
      borderStyle() {
        const {
          reload
        } = this
        const {
          borderStyle
        } = this.tabbarConfig
        if (reload) {}
        return borderStyle
      },
      tabbarBoxStyle() {
        const {
          zIndex,
          reload
        } = this
        if (reload) {}
        return obj2strStyle({
          'z-index': zIndex,
        })
      },
      tabbarFillStyle() {
        const {
          tabbarHeight,
          safeBottom,
          reload
        } = this
        if (reload) {}
        return obj2strStyle({
          'height': `${tabbarHeight}rpx`
        })
      },
      tabbarStyle() {
        const {
          tabbarHeight,
          reload
        } = this
        const {
          backgroundColor
        } = this.tabbarConfig
        if (reload) {}
        return obj2strStyle({
          // 'height': `${tabbarHeight}rpx`,
          'background-color': backgroundColor || '#fff',
        })
      },
      tabbarItemStyle() {
        const {
          currentIndex,
          reload
        } = this
        const {
          color,
          selectedColor
        } = this.tabbarConfig
        if (reload) {}
        return obj2strStyle({
          'color': currentIndex ? selectedColor : color
        })
      }
    },
    mounted() {
      this.initTabbar()
      this.getTabbarHeight()
    },
    methods: {
      getTabbarHeight() {
        var systemInfo = uni.getSystemInfoSync()
        var data = {
          ...systemInfo,
          tabbarH: 50, //tabbar高度--单位px
          tabbarPaddingB: 0, //tabbar底部安全距离高度--单位px
          device: systemInfo.system.indexOf('iOS') != -1 ? 'iOS' : 'Android', //苹果或者安卓设备
        }
        let modelArr = ['10,3', '10,6', 'X', 'XR', 'XS', '11', '12', '13', '14', '15', '16'];
        let model = systemInfo.model;
        model && modelArr.forEach(item => {
          //适配iphoneX以上的底部，给tabbar一定高度的padding-bottom
          if (model.indexOf(item) != -1 && (model.indexOf('iPhone') != -1 || model.indexOf('iphone') != -1)) {
            data.tabbarH = 70
            data.tabbarPaddingB = 20
          }
        })
        this.systemInfo = data
      },
      initTabbar() {
        const {
          current,
          fill,
          native,
          tabbarList
        } = this
        this.currentIndex = current * 1
        if (native) {
          const currentPage = `/${getCurrentPages()[0].route}`
          const currentIndex = tabbarList.findIndex(item => item.pagePath === currentPage)
          this.currentIndex = currentIndex
          if (tabbarList.length > 0) {
            uni.hideTabBar()
          }
        }
        setTimeout(() => {
          this.isShowTabBar = true
        })
      },
      reLoad() {
        this.reload = true
        setTimeout(() => {
          this.reload = false
        })
      },
      checkMaxIndex(index) {
        if (!this.tabbarConfig.list[index]) {
          console.error('Max tabbar index')
          return false
        }
        return true
      },
      setTabBarBadge(obj) {
        const {
          index,
          text
        } = obj
        if (this.checkMaxIndex(index)) {
          this.tabbarConfig.list[index].dot = text
          this.reLoad()
        }
      },
      setTabBarItem(obj) {
        const {
          index,
          text,
          pagePath: newPagePath,
          iconPath,
          selectedIconPath
        } = obj
        const {
          pagePath: oldPagePath
        } = this.tabbarConfig.list[index]
        if (this.checkMaxIndex(index)) {
          this.tabbarConfig.list[index] = {
            pagePath: newPagePath ? newPagePath : oldPagePath,
            text,
            iconPath,
            selectedIconPath
          }
          this.reLoad()
        }
      },
      showTabBar() {
        this.isShowTabBar = true
      },
      hideTabBar() {
        this.isShowTabBar = false
      },
      tabChange(index) {
        const { currentIndex } = this
        this.$emit('click', index)
        if (index === currentIndex) {
          index === 3 ? uni.$emit('resetLocation') : ''
          return
        }
        this.beforeData = {
          newIndex: index,
          oldIndex: currentIndex,
          next: this.jumpPage
        }
        if (this.beforeChange) {
          this.beforeChange(this.jumpPage)
        } else {
          this.jumpPage()
        }
      },
      jumpPage() {
        const {
          native,
          beforeData,
          tabbarList: list
        } = this
        const {
          newIndex: index
        } = beforeData
        const {
          pagePath: url,
          openType
        } = list[index]
        if (url) {
          if (native) {
            uni.switchTab({
              url
            })
          } else {
            this.currentIndex = index
            switch (openType) {
              case 'navigate':
                uni.navigateTo({
                  url
                })
                break;
              case 'redirect':
                uni.redirectTo({
                  url
                })
                break;
              case 'reLaunch':
                uni.reLaunch({
                  url
                })
                break;
              case 'switchTab':
                uni.switchTab({
                  url
                })
                break;
              case 'navigateBack':
                uni.navigateBack({
                  delta: 1
                })
                break;
              default:
                uni.reLaunch({
                  url
                })
            }
          }
        }
        this.$emit('change', index)
      }
    }
  };
</script>

<style lang="scss" scoped>
  .m-tabbar-box {
    position: relative;
    z-index: 9999;
  }

  .m-tabbar {
    position: relative;

    &.fixed {
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100vw;
    }

    &__safe {
      // padding-bottom: env(safe-area-inset-bottom);
    }
  }

  .m-tabbar__fill {
    pointer-events: none;
    opacity: 0;
  }

  .m-tabbar__flex {
    display: flex;
    flex-direction: row;
  }

  .m-tabbar__border {
    background-color: rgba(0, 0, 0, 0.33);
    width: 100%;
    height: 1rpx;
    transform: scaleY(0.5);
  }

  .m-tabbar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 1;
    padding: 4px 0 2px;
  }

  .m-tabbar__icon {
    width: 48rpx;
    height: 48rpx;
    margin-bottom: 6rpx;
    position: relative;

    &_img {
      display: block;
      width: 100%;
      height: 100%;
    }

    .m-tabbar__badge {
      color: #fff;
      background-color: #f00;
      border-radius: 20rpx;
      font-size: 22rpx;
      position: absolute;
      right: -25rpx;
      left: 40rpx;
      padding: 2rpx 0;
      width: 100%;
      text-align: center;
      white-space: nowrap;
    }
  }

  .m-tabbar__label {
    font-size: 24rpx;
  }
</style>