<script lang="ts" setup>
import { onShow } from '@dcloudio/uni-app'
import { getConfigByCode } from '@/api/common'
import { openH5WhatsApp } from '@/utils/social'
import { toast } from '@/utils/toast'

const props = defineProps<{
  bottomOffset?: number
}>()

const STORAGE_KEY = 'customer_service_fab_position_v1'

const x = ref<number>(0)
const y = ref<number>(0)

function rpxToPx(rpx: number) {
  const sys = uni.getSystemInfoSync()
  const windowWidth = sys.windowWidth || 375
  return (rpx * windowWidth) / 750
}

function getBottomLimitPx() {
  const sys = uni.getSystemInfoSync() as any
  const bottomOffsetPx = rpxToPx(props.bottomOffset ?? 0)
  const safeBottomPx = Number(sys?.safeAreaInsets?.bottom) || 0
  return bottomOffsetPx + safeBottomPx
}

function initDefaultPosition() {
  const sys = uni.getSystemInfoSync()
  const windowWidth = sys.windowWidth || 375
  const windowHeight = sys.windowHeight || 667
  const sizePx = rpxToPx(80)
  const rightInsetPx = rpxToPx(24)
  const bottomInsetPx = rpxToPx(-86)
  const bottomOffsetPx = getBottomLimitPx()
  x.value = Math.max(0, windowWidth - sizePx - rightInsetPx)
  y.value = Math.max(0, windowHeight - sizePx - bottomOffsetPx - bottomInsetPx)
}

function clampPosition() {
  const sys = uni.getSystemInfoSync()
  const windowWidth = sys.windowWidth || 375
  const windowHeight = sys.windowHeight || 667
  const sizePx = rpxToPx(80)
  const bottomOffsetPx = getBottomLimitPx()
  const maxX = Math.max(0, windowWidth - sizePx)
  const maxY = Math.max(0, windowHeight - sizePx - bottomOffsetPx)
  x.value = Math.min(Math.max(0, x.value), maxX)
  y.value = Math.min(Math.max(0, y.value), maxY)
}

function restorePosition() {
  try {
    const raw = uni.getStorageSync(STORAGE_KEY)
    if (!raw) {
      initDefaultPosition()
      return
    }
    const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw
    const nx = Number(parsed?.x)
    const ny = Number(parsed?.y)
    if (Number.isFinite(nx) && Number.isFinite(ny)) {
      x.value = nx
      y.value = ny
      clampPosition()
      return
    }
    initDefaultPosition()
  }
  catch {
    initDefaultPosition()
  }
}

function persistPosition() {
  try {
    uni.setStorageSync(STORAGE_KEY, JSON.stringify({ x: x.value, y: y.value }))
  }
  catch {
  }
}

function persistPositionClamped() {
  clampPosition()
  persistPosition()
}

onShow(() => {
  restorePosition()
})

function handleMoveChange(e: any) {
  const detail = e?.detail
  const nx = Number(detail?.x)
  const ny = Number(detail?.y)
  if (Number.isFinite(nx))
    x.value = nx
  if (Number.isFinite(ny))
    y.value = ny
  clampPosition()
}

async function openCustomerService() {
  try {
    const res = await getConfigByCode({ code: 'live_chat' })
    const value = res?.data?.valueInfo
    if (!value) {
      toast.info('客服暂不可用')
      return
    }
    openH5WhatsApp('live_chat', value)
  }
  catch {
    toast.info('客服暂不可用')
  }
}
</script>

<template>
  <movable-area class="customer-fab-area">
    <movable-view
      :x="x"
      :y="y"
      direction="all"
      :inertia="false"
      :animation="false"
      :out-of-bounds="false"
      class="customer-fab-movable"
      @change="handleMoveChange"
      @touchend="persistPositionClamped"
      @touchcancel="persistPositionClamped"
    >
      <image
        src="/static/icons/whatsapp.png"
        class="customer-fab-trigger__icon"
        mode="heightFix"
        @click="openCustomerService"
      />
    </movable-view>
  </movable-area>
</template>

<style lang="scss" scoped>
.customer-fab-area {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 999;
}

.customer-fab-movable {
  pointer-events: auto;
  transition: none;
  width: 80rpx;
  height: 80rpx;
}

.customer-fab-trigger__icon {
  box-shadow: 0 12rpx 30rpx rgba(0, 0, 0, 0.16);
  height: 80rpx;
  width: 80rpx;
  border-radius: 50%;
}
</style>
