<template>
  <view
    class="tn-custom-nav-bar-class tn-custom-nav-bar"
    :style="[navBarStyle]"
  >
  	<view
      class="tn-custom-nav-bar__bar"
      :class="[barClass]"
      :style="[barStyle]"
    >
      <view v-if="isBack">
        <view v-if="customBack">
          <view 
            :style="{
              width: customBackStyleInfo.width + 'px',
              height: customBackStyleInfo.height + 'px',
              marginLeft: customBackStyleInfo.left + 'px'
            }"
          >
            <slot name="back"></slot>
          </view>
        </view>
        <view v-else class="tn-custom-nav-bar__bar__action" @tap="handlerBack">
        	<text class="tn-custom-nav-bar__bar__action--nav-back" :class="[`tn-icon-${backIcon}`]"></text>
        	<text class="tn-custom-nav-bar__bar__action--nav-back-text" v-if="backTitle">{{ backTitle }}</text>
        </view>
      </view>
  		<view class="tn-custom-nav-bar__bar__content" :style="[contentStyle]">
  			<slot></slot>
  		</view>
  		<view>
        <slot name="right"></slot>
      </view>
  	</view>
  </view>
</template>

<script>
  import componentsColorMixin from '../../libs/mixin/components_color.js'
  export default {
    name: 'tn-nav-bar',
    mixins: [componentsColorMixin],
    props: {
      // 层级
      zIndex: {
        type: Number,
        default: 0
      },
      // 导航栏的高度
      height: {
        type: Number,
        default: 0
      },
      // 高度单位
      unit: {
        type: String,
        default: 'px'
      },
      // 是否显示返回按钮
      isBack: {
        type: Boolean,
        default: true
      },
      // 返回按钮的图标
      backIcon: {
        type: String,
        default: 'left'
      },
      // 返回按钮旁显示的文字
      backTitle: {
        type: String,
        default: '返回'
      },
      // 透明状态栏
      alpha: {
        type: Boolean,
        default: false
      },
      // 是否固定在顶部
      fixed: {
        type: Boolean,
        default: true
      },
      // 是否显示底部阴影
      bottomShadow: {
        type: Boolean,
        default: true
      },
      // 是否自定义返回按钮
      customBack: {
        type: Boolean,
        default: false
      },
      // 返回前回调
      beforeBack: {
        type: Function,
        default: null
      }
    },
    computed: {
      navBarStyle() {
        let style = {}
        style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit
        if (this.fixed) {
          style.position = 'fixed'
        }
        style.zIndex = this.elZIndex
        
        return style
      },
      barClass() {
        let clazz = ''
        if (this.backgroundColorClass) {
          clazz += ` ${this.backgroundColorClass}`
        }
        if (this.fontColorClass) {
          clazz += `${this.fontColorClass}`
        }
        if (this.fixed) {
          clazz += ' tn-custom-nav-bar__bar--fixed'
        }
        if (this.alpha) {
          clazz += ' tn-custom-nav-bar__bar--alpha'
        }
        if (this.bottomShadow) {
          clazz += ' tn-custom-nav-bar__bar--bottom-shadow'
        }
        
        return clazz
      },
      barStyle() {
        let style = {}
        style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit
        
        if (this.fixed) {
          style.paddingTop = this.statusBarHeight + 'px'
        }
        
        if(!this.backgroundColorClass) {
          style.backgroundColor = this.backgroundColor !== '' ? this.backgroundColor : '#FFFFFF'
        }
        if (!this.fontColorClass && this.fontColor) {
          style.color= this.fontColor
        }
        
        style.zIndex = this.elZIndex
        
        return style
      },
      contentStyle() {
        let style = {}
        style.top = this.fixed ? this.statusBarHeight + 'px' : '0px'
        style.height = this.height === 0 ? (this.customBarHeight - this.statusBarHeight) + this.unit : this.height + this.unit
        style.lineHeight = style.height
        
        if (this.isBack) {
          if (this.customBack) {
            const width = (this.customBackStyleInfo.width + this.customBackStyleInfo.left) * 2
            style.width = `calc(100% - ${width}px)`
          } else {
            style.width = 'calc(100% - 340rpx)'
          }
        } else {
          style.width = '100%'
        }
        
        return style
      },
      elZIndex() {
        return this.zIndex ? this.zIndex : this.$tn.zIndex.navbar
      }
    },
    data() {
      return {
        // 状态栏的高度
        statusBarHeight: 0,
        // 自定义导航栏的高度
        customBarHeight: 0,
        // 自定义返回按钮时，返回容器的宽高边距信息
        customBackStyleInfo: {
          width: 86,
          height: 32,
          left: 15
        }
      }
    },
    mounted() {
      // 获取vuex中的自定义顶栏的高度
      this.updateNavBarInfo()
    },
    created() {
      // 获取胶囊信息
      // #ifdef MP-WEIXIN
      let custom = wx.getMenuButtonBoundingClientRect()
      this.customBackStyleInfo.width = custom.width
      this.customBackStyleInfo.height = custom.height
      this.customBackStyleInfo.left = uni.upx2px(750) - custom.right
      // #endif
    },
    methods: {
      // 更新导航栏的高度
      async updateNavBarInfo() {
        // 获取vuex中的自定义顶栏的高度
        let customBarHeight = this.vuex_custom_bar_height
        let statusBarHeight = this.vuex_status_bar_height
        // 如果获取失败则重新获取
        if (!customBarHeight) {
          try {
            const navBarInfo = await this.$tn.updateCustomBar()
            customBarHeight = navBarInfo.customBarHeight
            statusBarHeight = navBarInfo.statusBarHeight
          } catch(e) {
            setTimeout(() => {
              this.updateNavBarInfo()
            }, 10)
            return
          }
        }
        
        // 更新vuex中的导航栏信息
        this && this.$tn.vuex('vuex_status_bar_height', statusBarHeight)
        this && this.$tn.vuex('vuex_custom_bar_height', customBarHeight)
        
        this.customBarHeight = customBarHeight
        this.statusBarHeight = statusBarHeight
      },
      // 处理返回事件
      async handlerBack() {
        if (this.beforeBack && typeof(this.beforeBack) === 'function') {
          // 执行回调，同时传入索引当作参数
          // 在微信，支付宝等环境(H5正常)，会导致父组件定义的函数体中的this变成子组件的this
          // 通过bind()方法，绑定父组件的this，让this的this为父组件的上下文
          let beforeBack = this.beforeBack.bind(this.$tn.$parent.call(this))()
          // 判断是否返回了Promise
          if (!!beforeBack && typeof beforeBack.then === 'function') {
            await beforeBack.then(res => {
              // Promise返回成功
              this.navBack()
            }).catch(err => {})
          } else if (beforeBack === true) {
            this.navBack()
          }
        } else {
          this.navBack()
        }
      },
      // 返回上一页
      navBack() {
        
        // 通过判断当前页面的页面栈信息，是否有上一页进行返回，如果没有则跳转到首页
        const pages = getCurrentPages()
        if (pages && pages.length > 0) {
          const firstPage = pages[0]
          if (pages.length == 1 && (!firstPage.route || firstPage.route != 'pages/index/index')) {
            uni.reLaunch({
              url: '/pages/index/index'
            })
          } else {
            uni.navigateBack({
              delta: 1
            })
          }
        } else {
          uni.reLaunch({
            url: '/pages/index/index'
          })
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
  
  .tn-custom-nav-bar {
    display: block;
    position: relative;
    
    &__bar {
      display: flex;
      position: relative;
      align-items: center;
      min-height: 100rpx;
      justify-content: space-between;
      min-height: 0px;
      /* #ifdef MP-WEIXIN */
      padding-right: 220rpx;
      /* #endif */
      /* #ifdef MP-ALIPAY */
      padding-right: 150rpx;
      /* #endif */
      box-shadow: 0rpx 0rpx 0rpx;
      z-index: 9999;
      
      &--fixed {
        position: fixed;
        width: 100%;
        top: 0;
      }
      
      &--alpha {
        background: transparent !important;
        box-shadow: none !important;
      }
      
      &--bottom-shadow {
        box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.05);
      }
      
      &__action {
        display: flex;
        align-items: center;
        height: 100%;
        justify-content: center;
        max-width: 100%;
        
        &--nav-back {
          /* position: absolute; */
          /* top: 50%; */
          /* left: 20rpx; */
          /* margin-top: -15rpx; */
          // width: 25rpx;
          // height: 25rpx;
          margin-left: 20rpx;
          font-size: 38rpx;
          line-height: 100%;
          // border-width: 0 0 4rpx 4rpx;
          // border-color: #000000;
          // border-style: solid;
          // transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
        }
        
        &--nav-back-text {
          margin-left: 10rpx;
        }
      }
      
      &__content {
        position: absolute;
        text-align: center;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        font-size: 32rpx;
        cursor: none;
        // pointer-events: none;
        text-overflow: ellipsis;
        white-space: nowrap;
        overflow: hidden;
      }
    }
  }
  
</style>
