<template>
  <Theme>
    <view class="wrap">
      <Navbar title="系统" fixed border />
      <view
        class="content"
        :style="{
          '--height': bottomHeight + 'px',
          '--keyboardHeight': keyboardHeight + 'px',
          '--contHeight': contHeight + 'px',
        }"
      >
        <scroll-view
          class="chat_content"
          scroll-anchoring
          :scroll-y="true"
          :scroll-top="scrollTop"
          :lower-threshold="lowerThreshold"
          :refresher-triggered="refresherTriggered"
          :refresher-enabled="refresherEnabled"
          @refresherrefresh="refresherrefresh"
          refresher-default-style="none"
          refresher-background="var(--bg)"
          @scroll="onScroll"
          @scrolltolower="onScrollLower"
        >
          <view class="refresher" v-if="refresherTriggered">
            <up-loadmore :status="'loading'" :loadingText="$t('正在加载')" />
          </view>
          <view class="scroll" id="scroll_items">
            <Message :list="msgList" />
          </view>
        </scroll-view>
      </view>
      <view
        class="new_count"
        :style="{ bottom: bottomHeight + 5 + 'px' }"
        v-show="newMessageCount > 0"
        @click="getContHeight"
      >
        <text>{{ newMessageCount }} {{ $t("条新消息") }}</text>
      </view>
      <footer-input
        v-model="message"
        @heights="getFooterHeight"
        @submit="send"
        @linechange="inputHeightChange"
        @imageUp="imageUp"
        ref="footerInputRef"
      />
    </view>
  </Theme>
</template>
<script setup>
import { onUnload, onLoad } from "@dcloudio/uni-app";
import { ref, nextTick, onMounted, reactive, watch, provide } from "vue";
import Navbar from "@/components/navbar";
import footerInput from "@/components/footer_input";
import Message from "@/components/message";
import { query, systemInfo, useGlobal } from "@/utils";
import { RONGIMCALL_HISTORY } from "@/api";
import { useSocketStore, useMessageStore } from "@/store";
import { storeToRefs } from "pinia";

const useSocket = useSocketStore();
const useMessage = useMessageStore();
const { messageMap } = storeToRefs(useMessage);
const bottomHeight = ref(0);
const scrollTop = ref(0);
const keyboardHeight = ref(0);
const contHeight = ref(0);
const newHeight = ref(0);
const message = ref("");
const footerInputRef = ref(null);

const refresherTriggered = ref(false);
const refresherEnabled = ref(true);
const msgList = ref([]);
const page = ref(1);
const pagesize = ref(10);
const total = ref(0);

const channel = ref("");
const firstMsg = ref({});
const lowerThreshold = ref(0);
const distanceFromBottom = ref(0);
const newMessageCount = ref(0);
const bottomSafeDistanceHeight = ref(0);

watch(
  () => messageMap.value,
  (newVal, oldVal) => {
    const info = newVal[channel.value];
    if (channel.value && info) {
      msgList.value = info.messageList;
      newMessageCount.value =
        distanceFromBottom.value > lowerThreshold.value ? info.unreadCount : 0;
    }
  },
  { deep: true, immediate: true }
);

provide("onQuestionSend", send);

function onScroll(e) {
  const { detail } = e;
  const distanceForBottom =
    detail.scrollHeight - detail.scrollTop - contHeight.value;
  distanceFromBottom.value = distanceForBottom > 0 ? distanceForBottom : 0;
  if (distanceFromBottom.value <= lowerThreshold.value) {
    useMessage.updateUnreadCount(channel.value, -1);
  }
}
function onScrollLower() {
  useMessage.updateUnreadCount(channel.value, -1);
}
const refresherrefresh = () => {
  refresherTriggered.value = true;
  if (total.value <= page.value * pagesize.value) {
    nextTick(() => {
      refresherTriggered.value = false;
    });
    return;
  }
  page.value += 1;
  nextTick(() => {
    getHistory(true);
  });
};

const getCont = () => {
  nextTick(() => {
    const { windowHeight, statusBarHeight } = systemInfo();
    contHeight.value = windowHeight - statusBarHeight - 44;
  });
};

const getContHeight = (isLoading) => {
  try {
    nextTick(async () => {
      const res = await query("#scroll_items");
      if (isLoading) {
        scrollTop.value = res.height - newHeight.value - 44;
      } else {
        scrollTop.value =
          res.height - bottomHeight.value - keyboardHeight.value - 44;
        const isIOS = uni.getSystemInfoSync().platform === "ios";
        if (isIOS) {
          scrollTop.value += bottomSafeDistanceHeight.value * 2;
        }
      }
      newHeight.value = res.height;
    });
  } catch (error) {}
};
const getFooterHeight = (res) => {
  nextTick(() => {
    bottomHeight.value = res.height || 0;
    keyboardHeight.value = res.keyboardHeight || 0;
    bottomSafeDistanceHeight.value = res.bottomSafeDistance || 0;
    getContHeight();
  });
};

function send(text) {
  sendMessage({ type: "text", text: text || message.value });
}

const imageUp = (url) => {
  sendMessage({ type: "image", url: url });
};

const sendMessage = (msgObject) => {
  let messageData = reactive({
    type: "notice",
    msg: JSON.stringify(msgObject),
    send: 1,
    loading: true,
    status: -1,
  });
  useMessage.updateMessageList(channel.value, messageData, "push");
  getContHeight();
  useMessage
    .sendMessage(msgObject, "notice")
    .then((data) => {
      messageData.loading = false;
      messageData.status = 1;
      for (let key in data) {
        if (key != "msg") {
          messageData[key] = data[key];
        }
      }
      useMessage.updateGlobalMapLasttime(`noticeChannel`, data.indate);
    })
    .catch(() => {
      messageData.loading = false;
      messageData.status = 0;
    });
  nextTick(() => {
    footerInputRef.value && footerInputRef.value.clear();
  });
};

const inputHeightChange = () => {
  // console.log("输入框高度发送变化");
};
const open = () => {
  useMessage
    .openChannel({
      type: "notice",
      socket_id: useSocket.socketId,
    })
    .then(async (res) => {
      firstMsg.value = res.data;
      channel.value = res.data.auth.channel;
      await getHistory();
      await clearCount();
    });
};

const getHistory = async (isLoading = false) => {
  try {
    let para = {
      page: page.value,
      pagesize: pagesize.value,
      type: "notice",
    };
    const res = await RONGIMCALL_HISTORY(para);
    const lists = res.data.lists;
    for (let i = 0; i < lists.length; i++) {
      const msgInfo = {
        ...lists[i],
        msg: JSON.parse(lists[i].msg),
      };
      useMessage.updateMessageList(channel.value, msgInfo, "unshift");
    }
    if (lists.length > 0 && page.value == 1) {
      let result = lists[0];
      let lastTime = result
        ? result.indate
        : (Date.now() / 1000).toFixed(0) - 0;
      useMessage.updateGlobalMapLasttime(`noticeChannel`, lastTime);
    }
    total.value = res.data.total;
    !total.value &&
      useMessage.updateMessageList(channel.value, firstMsg.value, "unshift");
    if (total.value <= page.value * pagesize.value) {
      nextTick(() => {
        refresherEnabled.value = false;
      });
    }
    nextTick(() => {
      getContHeight(isLoading);
      refresherTriggered.value = false;
    });
  } catch (error) {}
};

const clearCount = () => {
  useMessage.updateUnreadCount(channel.value, -1);
  useMessage.updateGlobalMapUnreadCount("noticeChannel", -1);
};

const openAndGetHistory = async () => {
  try {
    await open();
    await getCont();
    await getContHeight();
  } catch (error) {
    console.error(error);
  }
};
onMounted(() => {
  nextTick(() => {
    openAndGetHistory();
  });
});

onUnload(() => {
  useSocket.send({
    event: "pusher:unsubscribe",
    data: { channel: channel.value },
  });
  clearCount();
});
</script>
<style lang="less" scoped>
@import url("@/style.less");

.wrap {
  background: var(--bg);
  height: 100vh;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);

  .content {
    width: 100%;
    // padding: 0 30rpx;

    .chat_content {
      height: calc(var(--contHeight) - var(--keyboardHeight) - var(--height));

      .scroll {
        overflow: hidden;
      }
    }
  }

  .new_count {
    position: fixed;
    bottom: 0;
    right: 16rpx;
    z-index: 20;
    height: 52rpx;
    padding: 0 20rpx;
    border-radius: 26rpx;
    background-color: rgba(0, 0, 0, 1);
    color: #fff;
    font-size: 24rpx;
    line-height: 52rpx;
  }
}
</style>