<template>
  <Teleport to="body" :disabled="!appendToBody">
    <div
      class="wl-contact-xw"
      ref="contactXwRef"
      :style="styleEM"
      :class="{ 'dra-tran': showtran }"
      @touchstart.stop="handleDown"
      @click.stop
    >
      <Popover
        :placement="popoverPlacement"
        v-model:show="showPopover"
        trigger="click"
        class="contact-xw-popover"
      >
        <!-- 是卫瓴且非预发环境或者是灰度 -->
        <AlphaTest
          v-if="needGray || !isNormal"
          :isNormal="isNormal"
          :needGray="needGray"
          @openXWAi="openXWAi"
        />
        <template #reference>
          <div class="assistant-container">
            <div
              :style="{
                width: `${width}px`,
                height: `${height}px`,
              }"
              @click.stop="handleXWImg"
              class="assistant-content"
            >
              <img
                v-if="isHolidayShow"
                class="assistant-birthday-hat"
                alt=""
                :src="xw_third_anniversary"
              />
              <WlPic :src="src" round />
              <img class="assistant-ai" alt="" :src="xw_ai_icon" />
            </div>
          </div>
        </template>
      </Popover>
      <!-- <XWCodeUrl v-model="xwVisible" :tip="tipObj.tip" :url="tipObj.url" /> -->
    </div>
  </Teleport>
</template>

<script lang="ts">
/*
 * @Author: Lai.xianxu
 * @Date: 2023-03-03 11:18:59
 * @Last Modified by: Liao.xiuli
 * @Last Modified time: 2023-06-01 16:59:41
 */
export default {
  name: 'BCContactXW',
};
</script>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
import {
  xw_avatar,
  xw_ai_icon,
  xw_third_anniversary,
} from '@mobileUI/utils/cdn';
import listener from './listener';
import Store from '@mobileUI/store';
// import Api from '../api/index';
// import XWCodeUrl from "../components/XWCodeUrl.vue";
import WlPic from '@mobileUI/components/WlPic/src/index.vue';
import AlphaTest from '../components/AlphaTest.vue';
import { Popover } from 'vant';
import dayjs from 'dayjs';

const userSelectNone = {
  userSelect: 'none',
  MozUserSelect: 'none',
  WebkitUserSelect: 'none',
  MsUserSelect: 'none',
};

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

interface Props {
  src: string;
  width: number | string;
  height: number | string;
  x: number | string;
  y: number | string;
  marginX: number | string;
  bottomY: number | string;
  isRight: boolean;
  draggable: boolean;
  adsorb: boolean;
  scrollHide: boolean;
  scrollX: number | string;
  appendToBody: boolean;
  // tips: Array<string>;
  // noRepeatNum: number | string;
  env_data: TEnv.TEnvData;
  needGray: boolean;
}
const props = withDefaults(defineProps<Props>(), {
  src: Object.freeze(xw_avatar),
  /* 图标宽 */
  width: 40,
  /* 图标高 */
  height: 40,
  /* 初始x */
  x: 0,
  /* 初始y */
  y: 0,
  /* 吸附靠边边距 */
  marginX: 0,
  /* 初始距底距离 y为0时生效*/
  bottomY: -1,
  /* 初始是否靠右 x为0时生效*/
  isRight: false,
  /* 是否开启拖拽 */
  draggable: true,
  /* 是否开启吸附左右两侧 */
  adsorb: true,
  /* 是否开启滑动隐藏 adsorb为true时开启 */
  scrollHide: true,
  /* 滚动隐藏图标露出宽度 scrollHide为true时生效 */
  scrollX: 10,
  /* 是否挂载到body */
  appendToBody: true,
  /* 提示词 */
  // tips: () => {
  //   return [];
  // },
  /* 提示词不可重复次数 */
  // noRepeatNum: 3,
  /* 全局参数 */
  env_data: () => {
    return {};
  },
  // 是否需要灰度切换功能
  needGray: false,
});

const emit = defineEmits<{
  (e: 'dragstart', left: any, top: any): void;
  (e: 'dragging', left: any, top: any): void;
  (e: 'dragstop', left: any, top: any): void;
  // (e: "openEnterpriseChat", val: any): void;
}>();

const rawTop = ref(0); // 拖动中 top
const rawLeft = ref(0); // 拖动中 left
const top = ref(0); // 元素的 top
const left = ref(0); // 元素的 left
const bodyWidth = ref(0); // body元素宽
const bodyHeight = ref(0); // body元素高
const mouseClickPosition = ref({
  mouseX: 0,
  mouseY: 0,
  left: 0,
  top: 0,
}); // 鼠标点击的当前位置
const bounds = ref({
  minLeft: 0,
  maxLeft: 0,
  minTop: 0,
  maxTop: 0,
}); // 边界
const dragging = ref(false); // 拖动中
const showtran = ref(false); // 吸附动画
const startScroll = ref(0); // 初始滚动位置
const stopScroll = ref(0); // 结束滚动位置
// const xwVisible = ref(false); // 小微提示
const timer = ref(null); // 滚动计时器
// const tipObj = ref({
//   url: "", // 小微二维码
//   tip: "", // 提示词
//   ranNum:
//     props.noRepeatNum <= props.tips?.length
//       ? +props.noRepeatNum
//       : props.tips?.length, // 不可重复次数
//   hashList: [], // 使用的提示词集合
// }); //
const showPopover = ref(false); //
const isNormal = ref(true); // 是否正式版

/*  元素位置 */
const styleEM = computed((): any => {
  return {
    position: 'fixed',
    top: `${top.value}px`,
    left: `${left.value}px`,
    borderRadius: `${+props.height / 2}px`,
    ...(dragging.value ? userSelectNone : userSelectAuto),
  };
});
/* 当前元素靠左还是靠右 */
const isLeft = computed(() => {
  return left.value + +props.width / 2 < bodyWidth.value / 2;
});

/* 按钮显示位置 */
const popoverPlacement = computed(() => {
  let placement: any = isLeft.value ? 'top-start' : 'top-end';
  if (top.value < 150) {
    placement = isLeft.value ? 'bottom-start' : 'bottom-end';
  }
  return placement;
});

/* 元素top处理 */
watch(
  () => rawTop.value,
  (newTop) => {
    const boundsObj = bounds.value;
    if (boundsObj.maxTop === 0) {
      top.value = newTop;
      return;
    }
    // 超出边界处理
    if (boundsObj.minTop !== null && newTop < boundsObj.minTop) {
      newTop = boundsObj.minTop;
    } else if (boundsObj.maxTop !== null && boundsObj.maxTop < newTop) {
      newTop = boundsObj.maxTop;
    }

    top.value = newTop;
  }
);
/* 元素left处理 */
watch(
  () => rawLeft.value,
  (newLeft) => {
    const boundsObj = bounds.value;
    if (boundsObj.maxTop === 0) {
      left.value = newLeft;
      return;
    }
    // 防止拖出屏幕
    if (boundsObj.minLeft !== null && newLeft < boundsObj.minLeft) {
      newLeft = boundsObj.minLeft;
    } else if (boundsObj.maxLeft !== null && boundsObj.maxLeft < newLeft) {
      newLeft = boundsObj.maxLeft;
    }
    left.value = newLeft;
  }
);
watch(
  () => props.env_data,
  (val) => {
    Store.sid = val.sid;
    Store.corp_id = val.corp_id;
    Store.node_env = val.node_env;
    Store.token = val.token;
    Store.domain = val.domain;
  },
  {
    immediate: true,
    deep: true,
  }
);

/* 初始化 */
const init = () => {
  [bodyWidth.value, bodyHeight.value] = getBodySize();
  bounds.value = calcDragLimits();
  if (props.isRight && props.x == 0) {
    rawLeft.value = left.value = bounds.value.maxLeft;
  } else {
    rawLeft.value = +props.x < +props.marginX ? +props.marginX : +props.x;
  }
  rawTop.value = top.value =
    +props.bottomY >= 0 && props.y == 0
      ? bounds.value.maxTop - +props.bottomY
      : +props.y;
  if (props.adsorb) {
    listener.addEvent(document, 'scroll', handleScroll);
  }
};
/* 获取body宽高 */
const getBodySize = () => {
  const style = window.getComputedStyle(document.body, null);
  return [
    parseInt(style.getPropertyValue('width'), 10),
    parseInt(style.getPropertyValue('height'), 10),
  ];
};
/* 拖动区域计算 */
const calcDragLimits = () => {
  return {
    minLeft: 0 + +props.marginX,
    maxLeft: Math.floor(bodyWidth.value - +props.width - +props.marginX),
    minTop: 0,
    maxTop: Math.floor(bodyHeight.value - +props.height),
  };
};
/* 滑动时隐藏 */
const handleScroll = () => {
  showPopover.value = false;
  if (props.scrollHide) {
    if (timer.value) clearTimeout(timer.value);
    showtran.value = true;
    startScroll.value =
      document.documentElement.scrollTop || document.body.scrollTop;
    left.value = rawLeft.value = isLeft.value
      ? -parseInt(`${+props.width - +props.scrollX}`)
      : bounds.value.maxLeft +
        +props.marginX +
        parseInt(`${+props.width - +props.scrollX}`);
    timer.value = setTimeout(() => {
      stopScroll.value =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (stopScroll.value == startScroll.value) {
        resetX('scroll');
      }
    }, 350);
  }
};

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

//是不是预发布
const isPre = computed(() => props.env_data.node_env === 'stg');
//自动切回灰度
function autoBackToAlpha() {
  let d = new Date();
  d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000);
  let expires = 'expires=' + d.toUTCString();
  document.cookie = 'env=gray;path=/;' + expires;
  window.location.reload();
}
//判断是否是灰度环境
function judgeCookie() {
  let cookie = document.cookie;
  if (cookie?.includes('env=tmp-prod')) {
    isNormal.value = true;
    return;
  }
  if (cookie?.includes('env=gray')) {
    isNormal.value = false;
    return;
  }
  isNormal.value = true;
  //当手动切换过期后，刷新页面，切回灰度
  if (props.needGray && !isPre.value) {
    autoBackToAlpha();
  }
}

// 打开小微ai
const openXWAi = () => {
  window.open(
    `${props.env_data.domain}/xiaoshifu/xiaowei-home?target=out&corp_id=${props.env_data?.corp_id}&token=${props.env_data?.token}&channel=worktableH5`
  );
};

// 判断生日帽是否展示
const isHolidayShow = computed(() => {
  const nowTime = dayjs().valueOf();
  const holidayTime = dayjs('2023-12-15').valueOf();
  return nowTime < holidayTime;
});

onMounted(() => {
  init();
  judgeCookie();
});

onBeforeUnmount(() => {
  listener.removeEvent(
    document.querySelector('.wl-contact-xw'),
    'touchstart',
    handleDown
  );
  listener.removeEvent(
    document.querySelector('.wl-contact-xw'),
    'touchmove',
    move
  );
  listener.removeEvent(
    document.querySelector('.wl-contact-xw'),
    'touchend',
    handleUp
  );
});
</script>

<style lang="scss" scoped>
.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);
  display: flex;
  align-items: center;
  justify-content: center;
  .assistant-content {
    position: relative;
    box-shadow: 0px 0px 12.8671px rgba(0, 0, 0, 0.08);
    border-radius: 50%;
    .assistant-birthday-hat {
      position: absolute;
      left: -12%;
      top: -40%;
      width: 92%;
      z-index: 1;
    }
    .assistant-ai {
      position: absolute;
      width: 100%;
      bottom: -28%;
      border-radius: j(5);
    }
  }
}
</style>
<style lang="scss">
.contact-xw-popover.van-popover--light {
  width: fit-content;
  height: fit-content;
  background: transparent !important;
  .van-popover__content {
    background: transparent;
    box-shadow: none;
  }
  .van-popover__arrow {
    color: transparent;
  }
}
</style>
