<template>
  <div
    class="wl-contact-xw"
    :style="style"
    :class="{ 'dra-tran': showtran }"
    @touchstart.stop="handleDown"
    @click.stop
  >

    <van-popover
        placement="left"
        v-model="showPopover"
        :overlay="false"
        trigger="click"
        get-container=".wl-contact-xw"
      >
      <template #reference>
        <div class="assistant-container">
          <div
            :style="{
              width: `${width}px`,
              height: `${height}px`,
            }"
            @click.stop="onContactXW"
            class="assistant-content"
          >
            <WlPic :src="src" round />
          </div>
          <img v-if="needSwitch && versionStatus && !isNormal" class="assistant-status" alt="" src="https://wlmvp-cos.weiling.cn/worktable-erp/tryVersion/newVersionTip.png"/>
        </div>
      </template>
      <AlphaTest />
    </van-popover>
    <XWCodeUrl v-model="xwVisible" :tip="tipObj.tip" :url="tipObj.url" />
  </div>
</template>

<script>
import { xw_avatar } from '@packages/utils/cdn';
import listener from './listener';
import Store from '@packages/store/index.js';
import Api from '../api/index';
import XWCodeUrl from '../components/XWCodeUrl.vue';
import WlPic from '@packages/components/Common/WlPic/src/index.vue';
import AlphaTest from '../components/AlphaTest.vue';
const userSelectNone = {
  userSelect: 'none',
  MozUserSelect: 'none',
  WebkitUserSelect: 'none',
  MsUserSelect: 'none',
};

const userSelectAuto = {
  userSelect: 'auto',
  MozUserSelect: 'auto',
  WebkitUserSelect: 'auto',
  MsUserSelect: 'auto',
};

export default {
  name: 'WlContactXW',
  components: { XWCodeUrl, WlPic, AlphaTest },
  props: {
    /* 图标 */
    src: {
      type: String,
      default: Object.freeze(xw_avatar),
    },
    /* 图标宽 */
    width: {
      type: [Number, String],
      default: 40,
    },
    /* 图标高 */
    height: {
      type: [Number, String],
      default: 40,
    },
    /* 初始x */
    x: {
      type: [Number, String],
      default: 0,
    },
    /* 初始y */
    y: {
      type: [Number, String],
      default: 0,
    },
    /* 吸附靠边边距 */
    marginX: {
      type: [Number, String],
      default: 0,
    },
    /* 初始距底距离 y为0时生效*/
    bottomY: {
      type: [Number, String],
      default: -1,
    },
    /* 初始是否靠右 x为0时生效*/
    isRight: {
      type: Boolean,
      default: false,
    },
    /* 是否开启拖拽 */
    draggable: {
      type: Boolean,
      default: true,
    },
    /* 是否开启吸附左右两侧 */
    adsorb: {
      type: Boolean,
      default: true,
    },
    /* 是否开启滑动隐藏 adsorb为true时开启 */
    scrollHide: {
      type: Boolean,
      default: true,
    },
    /* 滚动隐藏图标露出宽度 scrollHide为true时生效 */
    scrollX: {
      type: [Number, String],
      default: 10,
    },
    /* 是否挂载到body */
    appendToBody: {
      type: Boolean,
      default: false,
    },
    /* 提示词 */
    tips: {
      type: Array,
      default: () => {
        return [];
      },
    },
    /* 提示词不可重复次数 */
    noRepeatNum: {
      type: [Number, String],
      default: 3,
    },
    /* 全局参数 */
    env_data: {
      type: Object,
      default: () => {
        return {
          sid: '',
          corp_id: '',
          node_env: '',
        };
      },
    },
    // 是否需要灰度切换功能
    needSwitch: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      rawTop: 0, // 拖动中 top
      rawLeft: 0, // 拖动中 left
      top: 0, // 元素的 top
      left: 0, // 元素的 left
      bodyWidth: 0, // body元素宽
      bodyHeight: 0, // body元素高
      mouseClickPosition: {
        // 鼠标点击的当前位置
        mouseX: 0,
        mouseY: 0,
        left: 0,
        top: 0,
      },
      bounds: {
        // 边界
        minLeft: 0,
        maxLeft: 0,
        minTop: 0,
        maxTop: 0,
      },
      dragging: false, // 拖动中
      showtran: false, // 吸附动画
      startScroll: 0, // 初始滚动位置
      stopScroll: 0, // 结束滚动位置
      xwVisible: false, // 小微提示
      timer: null, // 滚动计时器
      tipObj: {
        url: '', // 小微二维码
        tip: '', // 提示词
        ranNum:
          this.noRepeatNum <= this.tips.length
            ? this.noRepeatNum
            : this.tips.length, // 不可重复次数
        hashList: [], // 使用的提示词集合
      },
      showPopover: false,
      // 是否显示版本
      versionStatus: true,
      //是否正式版
      isNormal: true
    };
  },
  created() {
    this.judgeCookie();
  },
  computed: {
    /*  元素位置 */
    style() {
      return {
        position: 'fixed',
        top: `${this.top}px`,
        left: `${this.left}px`,
        borderRadius: `${+this.height / 2}px`,
        ...(this.dragging ? userSelectNone : userSelectAuto),
      };
    },
    /* 当前元素靠左还是靠右 */
    isLeft() {
      return this.left + +this.width / 2 < this.bodyWidth / 2;
    },
  },
  watch: {
    /* 元素top处理 */
    rawTop: {
      handler(newTop) {
        const bounds = this.bounds;
        if (bounds.maxTop === 0) {
          this.top = newTop;
          return;
        }
        // 超出边界处理
        if (bounds.minTop !== null && newTop < bounds.minTop) {
          newTop = bounds.minTop;
        } else if (bounds.maxTop !== null && bounds.maxTop < newTop) {
          newTop = bounds.maxTop;
        }

        this.top = newTop;
      },
    },
    /* 元素left处理 */
    rawLeft: {
      handler(newLeft) {
        const bounds = this.bounds;
        if (bounds.maxTop === 0) {
          this.left = newLeft;
          return;
        }
        // 防止拖出屏幕
        if (bounds.minLeft !== null && newLeft < bounds.minLeft) {
          newLeft = bounds.minLeft;
        } else if (bounds.maxLeft !== null && bounds.maxLeft < newLeft) {
          newLeft = bounds.maxLeft;
        }
        this.left = newLeft;
      },
    },
    // 全局参数配置
    env_data: {
      handler(val) {
        Store.sid = val.sid;
        Store.corp_id = val.corp_id;
        Store.node_env = val.node_env;
      },
      immediate: true,
      deep: true,
    },
    showPopover: {
      handler(val) {
        this.versionStatus = !val;
      }
    }
  },
  mounted() {
    this.init();
  },
  methods: {
    /* 挂载到body */
    onAppendToBody() {
      this.$nextTick(() => {
        const body = document.querySelector('body');
        if (body.append) {
          body.append(this.$el);
        } else {
          body.appendChild(this.$el);
        }
      });
    },
    /* 初始化 */
    init() {
      if (this.appendToBody) this.onAppendToBody();
      [this.bodyWidth, this.bodyHeight] = this.getBodySize();
      this.bounds = this.calcDragLimits();
      if (this.isRight && this.x == 0) {
        this.rawLeft = this.left = this.bounds.maxLeft;
      } else {
        this.rawLeft = +this.x < +this.marginX ? +this.marginX : +this.x;
      }
      this.rawTop = this.top =
        +this.bottomY >= 0 && this.y == 0
          ? this.bounds.maxTop - +this.bottomY
          : +this.y;
      if (this.adsorb) {
        listener.addEvent(document, 'scroll', this.handleScroll);
      }
    },
    /* 获取body宽高 */
    getBodySize() {
      const style = window.getComputedStyle(document.body, null);
      return [
        parseInt(style.getPropertyValue('width'), 10),
        parseInt(style.getPropertyValue('height'), 10),
      ];
    },
    /* 拖动区域计算 */
    calcDragLimits() {
      return {
        minLeft: 0 + +this.marginX,
        maxLeft: Math.floor(this.bodyWidth - +this.width - +this.marginX),
        minTop: 0,
        maxTop: Math.floor(this.bodyHeight - +this.height),
      };
    },
    /* 滑动时隐藏 */
    handleScroll() {
      if (this.scrollHide) {
        if (this.timer) clearTimeout(this.timer);
        this.showtran = true;
        this.startScroll =
          document.documentElement.scrollTop || document.body.scrollTop;
        this.left = this.rawLeft = this.isLeft
          ? -parseInt(+this.width - this.scrollX)
          : this.bounds.maxLeft +
            +this.marginX +
            parseInt(+this.width - this.scrollX);
        this.timer = setTimeout(() => {
          this.stopScroll =
            document.documentElement.scrollTop || document.body.scrollTop;
          if (this.stopScroll == this.startScroll) {
            this.resetX('scroll');
          }
        }, 350);
      }
    },

    /* 鼠标点击/触摸开始 */
    handleDown(e) {
      if (this.draggable) {
        this.elementDown(e);
      }
    },
    elementDown(e) {
      this.mouseClickPosition.left = this.left;
      this.mouseClickPosition.top = this.top;
      this.mouseClickPosition.mouseX = e.touches ? e.touches[0].pageX : e.pageX;
      this.mouseClickPosition.mouseY = e.touches ? e.touches[0].pageY : e.pageY;
      this.$emit('dragstart', this.left, this.top);
      // 监听拖动、结束事件
      listener.addEvent(
        document.querySelector('.wl-contact-xw'),
        'touchmove',
        this.move
      );
      listener.addEvent(
        document.querySelector('.wl-contact-xw'),
        'touchend',
        this.handleUp
      );
    },
    /* 拖拽过程 */
    move(e) {
      this.dragging = true;
      this.elementMove(e);
    },
    elementMove(e) {
      const mouseClickPosition = this.mouseClickPosition;
      const tmpDeltaX =
        mouseClickPosition.mouseX -
          (e.touches ? e.touches[0].pageX : e.pageX) || 0;
      const tmpDeltaY =
        mouseClickPosition.mouseY -
          (e.touches ? e.touches[0].pageY : e.pageY) || 0;
      if (!tmpDeltaX && !tmpDeltaY) return;
      this.rawTop = mouseClickPosition.top - tmpDeltaY;
      this.rawLeft = mouseClickPosition.left - tmpDeltaX;
      this.$emit('dragging', this.rawLeft, this.rawTop);
    },
    /* 拖拽结束 */
    handleUp() {
      this.rawTop = this.top;
      this.rawLeft = this.left;
      if (this.dragging) this.dragging = false;
      this.resetX();
    },
    /* 左右吸附 */
    resetX(type) {
      if (this.adsorb) {
        this.showtran = true;
        this.rawLeft = this.isLeft ? this.bounds.minLeft : this.bounds.maxLeft;
        setTimeout(() => {
          this.showtran = false;
        }, 400);
      }
      if (type != 'scroll') this.$emit('dragstop', this.rawLeft, this.rawTop);
      this.resetBoundsAndMouseState();
    },
    /* 重置初始数据 */
    resetBoundsAndMouseState() {
      this.mouseClickPosition = {
        mouseX: 0,
        mouseY: 0,
        left: 0,
        top: 0,
      };
    },
    /* 联系小微 */
    async onContactXW() {
      if(this.needSwitch) {
        this.showPopover = !this.showPopover;
        return
      }
      const { data } = await Api.getXwCodeInfo({
        scene: 'contact_xw_for_help_mobile',
      });
      if (
        data.external_user_vo?.external_userid_open &&
        /wxwork/i.test(window.navigator.userAgent.toLowerCase()) // 企微环境
      ) {
        this.$emit('openEnterpriseChat', data.external_user_vo);
        return
      }
      this.tipObj.tip = this.getTips();
      this.tipObj.url = data.xw_code_url;
      this.xwVisible = true;
    },
    /* 获取提示 */
    getTips() {
      while (this.tipObj.ranNum > 0) {
        let i = Math.floor(Math.random() * this.tips.length);
        if (!this.tipObj.hashList.includes(this.tips[i])) {
          this.tipObj.hashList.push(this.tips[i]);
          this.tipObj.ranNum--;
          if (this.tipObj.ranNum == 0) {
            this.tipObj.ranNum = 1;
            this.tipObj.hashList.shift();
          }
          return this.tips[i];
        }
      }
    },

    judgeCookie() {
      let cookie = document.cookie;
      if (cookie.includes("env=gray")) {
        this.isNormal = false;
      } else {
        this.isNormal = true;
      }
    },
  },
  beforeDestroy() {
    listener.removeEvent(
      document.querySelector('.wl-contact-xw'),
      'touchstart',
      this.handleDown
    );
    listener.removeEvent(
      document.querySelector('.wl-contact-xw'),
      'touchmove',
      this.move
    );
    listener.removeEvent(
      document.querySelector('.wl-contact-xw'),
      'touchend',
      this.handleUp
    );
  },
};
</script>

<style lang="scss" scoped>

::v-deep .van-popover[data-popper-placement=left]{
  width: fit-content;
  height: fit-content;
  .van-popover__content {
    background-color: transparent;
    box-shadow: none;
    position: relative;
    top: j(-6);
    left: j(20);
  }
} 
.wl-contact-xw {
  display: inline-flex;
  align-items: center;
  border-radius: 20px;
  touch-action: none;
  // overflow: hidden;
  
}
.dra-tran {
  transition: all 0.2s ease-out;
}

.assistant-container {
  width: j(71);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  .assistant-content {
    box-shadow: 0px 0px 12.8671px rgba(0, 0, 0, 0.08);
    border-radius: 50%;
  }
  .assistant-status {
    position: absolute;
    bottom: j(-22);
    width: j(71);
    height: j(24);
    border-radius: 4px;
  }
}
</style>
