<!--
    @name: index
    @author: kahu4
    @date: 2023-11-09 10:56
    @description：index
    @update: 2023-11-09 10:56
-->
<script setup>
import { computed, defineProps, ref, toRefs, unref, watch } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { useRouter } from "@/hooks/useRouter";
import { createAnimation } from "@/utils/utils";
import { useScroll } from "@/hooks/useScroll";

const HEADER_HEIGHT = 60 // header高度

const {goBack} = useRouter()
/**
 * @property {String} systemBarAreaBg 系统导航条区域背景颜色
 * @property {String} headerAreaBg header区域背景颜色
 * @property {String} headerAreaTextColor header区域字体
 * @property {Boolean} showReturn 是否展示返回按钮
 * @property {String} returnColor 返回按钮的颜色
 * @property {Number} returnSize 返回按钮的大小
 * @property {Boolean||String} textShadow 字体阴影
 * @property {Boolean} bgChangeByScroll 是否随着页面滚动增加header背景（包括system-bar-area）
 * @property {String} bgChangeColor 滚动时候变换的颜色
 * @property {Number} scrollTop 当前页面高度
 * @property {Boolean} showRight 是否需要右边
 * @property {number} leftWidth 左侧（返回）宽度（设置了此属性title将不再居中）
 *
 */
const props = defineProps({
  scrollTop:{
    type:Number,
    default:()=>0
  },
  systemBarAreaBg: {
    type: String,
    default: () => '#FFFFFF00' // 透明 #FFFFFF00
  },
  headerAreaBg: {
    type: String,
    default: () => '#FFFFFF00' // 透明 #FFFFFF00
  },
  headerAreaTextColor: {
    type: String,
    default: () => '#000000'
  },
  showReturn: {
    type: Boolean,
    default: () => true
  },
  returnColor: {
    type: String,
    default: () => '#000'
  },
  returnSize: {
    type: Number,
    default: () => 22
  },
  textShadow: {
    type: [Boolean, String],
    default: () => false
  },
  bgChangeByScroll: {
    type: Boolean,
    default: () => true
  },
  bgChangeColor: {
    type: String,
    default: () => '#fff'
  },
  propUp: {
    type: Boolean,
    default: () => true
  },
  showRight: {
    type: Boolean,
    default: () => true
  },
  leftWidth: {
    type: Number,
    default: () => 0
  }
})

const {
  systemBarAreaBg,
  headerAreaBg,
  headerAreaTextColor,
  showReturn,
  returnColor,
  returnSize,
  textShadow,
  bgChangeByScroll,
  bgChangeColor,
  propUp,
  showRight,
  leftWidth,
  scrollTop
} = toRefs(props)

const emits = defineEmits(['getSystemInfo', 'animation'])


// 高度信息 单位px
const heightInfo = ref({
  safeAreaInsets: {bottom: 0, top: 0, left: 0, right: 0}, // 安全区信息
  statusBarHeight: 0, // 状态栏高度
  screenWidth: 0, // 屏幕内部宽度
  screenHeight: 0, // 屏幕内部高度
})

/**
 * 获取系统信息，设置导航条
 */
function getSystemInfo() {
  const res = uni.getSystemInfoSync();
  const heightObj = unref(heightInfo)
  heightObj.safeAreaInsets = res.safeAreaInsets
  heightObj.statusBarHeight = res.statusBarHeight
  heightObj.screenWidth = res.screenWidth || res.windowWidth
  heightObj.screenHeight = res.screenHeight || res.windowHeight
}

// 胶囊信息 单位px
const menuInfo = ref({
  bottom: 0,
  height: 0,
  left: 0,
  right: 0,
  top: 0,
  width: 0
})

/**
 * 获取小程序右上角信息
 */
function getMenuInfo() {
  const menuButtonBoundingClientRect = uni.getMenuButtonBoundingClientRect();
  if (menuButtonBoundingClientRect) {
    menuInfo.value = {...menuButtonBoundingClientRect}
  }
}

// scss全局变量
const scssVarStyle = computed(() => {
  return {
    '--header-height': `${ HEADER_HEIGHT }px`
  }
})

// 系统导航条区域样式
const systemBarAreaStyle = computed(() => {
  return {
    width: '100%',
    height: `${ unref(heightInfo).statusBarHeight * 2 }rpx`,
    background: unref(systemBarAreaBg)
  }
})

// header区域样式
const headerAreaStyle = computed(() => {
  // 计算margin top
  // margin-top (导航条高度 - 胶囊高度) / 2 永远确保胶囊在header中央
  const marginTop = unref(menuInfo).height > 0 ? `-${((HEADER_HEIGHT - unref(menuInfo).height))/2}px` : 0
  return {
    width: '100%',
    background: unref(headerAreaBg),
    color: unref(headerAreaTextColor),
    marginTop
  }
})

// 文本样式
const textShadowStyle = computed(() => {
  return {
    textShadow: unref(textShadow) ? unref(textShadow) : 'none',
  }
})

const titleStyle = computed(() => {
  let width = unref(leftWidth) <= 0 ? '' : `calc( 100vw - var(--side-distance) - var(--side-distance) - ${ leftWidth.value }rpx )`
  // #ifdef MP-WEIXIN
  width = unref(leftWidth) <= 0 ? '' : `calc( 100vw - var(--side-distance) - var(--side-distance) - ${ leftWidth.value }rpx - ${ menuInfo.value.width }px )`
  // #endif
  return {
    width,
    left: unref(leftWidth) <= 0 ? '50%' : `calc( var(--side-distance) + ${ leftWidth.value }rpx )`,
    textShadow: unref(textShadow) ? unref(textShadow) : 'none',
    transform: unref(leftWidth) <= 0 ? 'translateX(-50%) translateY(-50%)' : 'translateX(0) translateY(-50%)'
  }
})

// 滚动后背景样式
const scrollMaskStyle = computed(() => {
  return {
    background: unref(bgChangeColor),
    opacity: unref(scrollTransparency)
  }
})

// 总高度
const containerHeight = computed(() => {
  const marginTop = unref(menuInfo).height > 0 ? `${((HEADER_HEIGHT - unref(menuInfo).height))/2}` : 0
  return (unref(heightInfo).statusBarHeight + HEADER_HEIGHT - marginTop)
})

let animation
const scrollTransparency = ref(0) // 滚动透明度
function doCreateAnimation() {
  const scrollEnd = heightInfo.value.safeAreaInsets.bottom + HEADER_HEIGHT + 100
  animation = createAnimation(0, scrollEnd, 0, 1)
}

watch(scrollTop, () => {
  if (!bgChangeByScroll.value) return
  if (!animation) doCreateAnimation()
  scrollTransparency.value = animation(unref(scrollTop));
  emits('animation', scrollTransparency.value)
})


defineExpose({containerHeight, heightInfo})

onLoad(() => {
  getSystemInfo()
  doCreateAnimation()
  // #ifdef MP-WEIXIN
  getMenuInfo()
  // #endif
})
</script>

<template>
  <view
      class="container"
      :style="scssVarStyle"
  >
    <view class="header-container">
      <!-- 头部系统导航条区域 -->
      <view
          class="system-bar-area"
          :style="systemBarAreaStyle"
      >

      </view>
      <!-- header -->
      <view
          class="header-row"
          :style="headerAreaStyle"
      >
        <view
            class="left"
            :style="textShadowStyle"
            v-if="showReturn"
        >
          <slot name="left">
            <uv-icon
                name="arrow-left"
                :color="returnColor"
                :size="returnSize"
                @click="goBack"
            />
          </slot>
        </view>
        <view
            class="title"
            :style="titleStyle"
        >
          <slot>
          </slot>
        </view>
        <view
            class="right"
            v-if="showRight"
        >
          <slot name="right">
          </slot>
        </view>
      </view>

      <!-- 背景 mask -->
      <view
          class="bg-mask"
          :style="scrollMaskStyle"
      ></view>

    </view>
    <!-- 撑起 -->
    <view
        class="prop-up"
        :style="{height:`${containerHeight}px`}"
        v-if="propUp"
    ></view>
  </view>
</template>

<style
    scoped
    lang="scss"
>

.container {
  --header-height: 0rpx;
  --side-distance: 30rpx;
  $side-distance: var(--side-distance); // 侧边距
  $header-height: var(--header-height); // header高度
  .header-container {
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99;

    .system-bar-area {
      width: 100%;
      z-index: 1;
    }

    .header-row {
      z-index: 1;
      width: 100%;
      height: $header-height;
      position: relative;

      .left, .right, .title {
        position: absolute;
        top: 50%;
        height: 100%;
        transform: translateY(-50%);
        display: flex;
        align-items: center;
      }

      .left {
        left: $side-distance;
      }

      .right {
        right: $side-distance;
      }

      .title {
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
        color: #333;
      }
    }

    .bg-mask {
      z-index: 0;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      opacity: 0;
      box-shadow: 0 0 15rpx rgba(162, 162, 162, 0.5);
    }
  }

  .prop-up {
    width: 100%;
    height: $header-height;
  }
}

</style>
