<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, useSlots, nextTick } from 'vue'
import { useSettingsStore } from '../stores/settings'
import { clamp } from '../utils'

interface Props {
  id: string
  title?: string
  width?: number
  height?: number
}

const props = withDefaults(defineProps<Props>(), {
  title: '',
  width: 300,
  height: 200
})

const settingsStore = useSettingsStore()
const slots = useSlots()

const elementRef = ref<HTMLElement | null>(null)
const isMounted = ref(false)
const isDragging = ref(false)
const dragStartPos = ref({ x: 0, y: 0 })
const elementStartPos = ref({ x: 0, y: 0 })

const isMobile = computed(() => settingsStore.isMobile)

const widgetState = computed(() => {
  return settingsStore.widgets.find(w => w.id === props.id)
})

const position = computed(() => {
  if (isMobile.value || !isMounted.value) return { x: 0, y: 0 }
  return widgetState.value?.position ?? getDefaultPosition()
})

const order = computed(() => {
  return widgetState.value?.order ?? 0
})

const blurAmount = computed(() => settingsStore.theme.blurAmount ?? 20)
const backgroundColor = computed(() => settingsStore.theme.backgroundColor ?? 'rgba(30, 30, 30, 0.7)')

function getDefaultPosition() {
  const screenWidth = typeof window !== 'undefined' ? window.innerWidth : 1920
  const screenHeight = typeof window !== 'undefined' ? window.innerHeight : 1080
  
  const positions: Record<string, { x: number; y: number }> = {
    calendar: { x: screenWidth - 340, y: 20 },
    taoxin: { x: screenWidth - 320, y: screenHeight - 380 },
    cafe: { x: screenWidth - 660, y: 20 }
  }
  
  return positions[props.id] ?? { x: 20, y: 20 }
}

onMounted(async () => {
  await nextTick()
  
  const storedData = localStorage.getItem('wufangzhen-settings')
  const parsed = storedData ? JSON.parse(storedData) : null
  const storedWidget = parsed?.widgets?.find((w: { id: string }) => w.id === props.id)
  
  if (!storedWidget) {
    const defaultPos = getDefaultPosition()
    settingsStore.updateWidgetPosition(props.id, defaultPos)
  }
  
  isMounted.value = true
})

function handleDragStart(e: MouseEvent | TouchEvent, clientX: number, clientY: number) {
  if (isMobile.value || !isMounted.value) return
  e.preventDefault()
  isDragging.value = true
  dragStartPos.value = { x: clientX, y: clientY }
  elementStartPos.value = { ...position.value }
  
  if (e instanceof MouseEvent) {
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
  } else {
    document.addEventListener('touchmove', handleTouchMove, { passive: false })
    document.addEventListener('touchend', handleTouchEnd)
  }
}

function handleMouseDown(e: MouseEvent) {
  handleDragStart(e, e.clientX, e.clientY)
}

function handleTouchStart(e: TouchEvent) {
  if (e.touches.length !== 1) return
  handleDragStart(e, e.touches[0].clientX, e.touches[0].clientY)
}

function handleMouseMove(e: MouseEvent) {
  if (!isDragging.value) return
  updatePosition(e.clientX, e.clientY)
}

function handleTouchMove(e: TouchEvent) {
  if (!isDragging.value || e.touches.length !== 1) return
  e.preventDefault()
  updatePosition(e.touches[0].clientX, e.touches[0].clientY)
}

function updatePosition(clientX: number, clientY: number) {
  const deltaX = clientX - dragStartPos.value.x
  const deltaY = clientY - dragStartPos.value.y

  const maxX = window.innerWidth - props.width - 20
  const maxY = window.innerHeight - props.height - 100

  const newX = clamp(elementStartPos.value.x + deltaX, 20, maxX)
  const newY = clamp(elementStartPos.value.y + deltaY, 20, maxY)

  settingsStore.updateWidgetPosition(props.id, { x: newX, y: newY })
}

function handleMouseUp() {
  isDragging.value = false
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

function handleTouchEnd() {
  isDragging.value = false
  document.removeEventListener('touchmove', handleTouchMove)
  document.removeEventListener('touchend', handleTouchEnd)
}

onUnmounted(() => {
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
  document.removeEventListener('touchmove', handleTouchMove)
  document.removeEventListener('touchend', handleTouchEnd)
})
</script>

<template>
  <div
    v-if="isMobile"
    class="widget-mobile"
    :style="{ order: order }"
  >
    <div class="widget-mobile-header" v-if="title">
      <span class="widget-title">{{ title }}</span>
    </div>
    <div class="widget-mobile-content">
      <slot></slot>
    </div>
  </div>
  <div
    v-else-if="isMounted"
    ref="elementRef"
    class="widget"
    :class="{ 'widget-dragging': isDragging }"
    :style="{
      left: position.x + 'px',
      top: position.y + 'px',
      width: width + 'px',
      height: height + 'px'
    }"
  >
    <div 
      class="widget-drag-handle"
      @mousedown="handleMouseDown"
      @touchstart="handleTouchStart"
    >
      <div class="drag-indicator"></div>
      <span class="widget-title" v-if="title">{{ title }}</span>
    </div>
    <div class="widget-content">
      <slot></slot>
    </div>
  </div>
</template>

<style scoped>
.widget {
  position: absolute;
  border-radius: 16px;
  background: v-bind('settingsStore.theme.backgroundColor');
  backdrop-filter: blur(v-bind('settingsStore.theme.blurAmount + "px"'));
  -webkit-backdrop-filter: blur(v-bind('settingsStore.theme.blurAmount + "px"'));
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  user-select: none;
  transition: box-shadow 0.2s ease;
  display: flex;
  flex-direction: column;
}

.widget:hover {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
}

.widget-dragging {
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
  z-index: 50;
}

.widget-drag-handle {
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  cursor: grab;
  background: rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
}

.widget-drag-handle:active {
  cursor: grabbing;
}

.drag-indicator {
  width: 40px;
  height: 4px;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 2px;
}

.widget-title {
  font-size: 14px;
  font-weight: 600;
  color: white;
}

.widget-content {
  flex: 1;
  padding: 16px;
  overflow: hidden;
  cursor: default;
  min-height: 0;
}

.widget-mobile {
  width: calc(100% - 20px);
  margin: 10px;
  border-radius: 16px;
  background: v-bind('settingsStore.theme.backgroundColor');
  backdrop-filter: blur(v-bind('settingsStore.theme.blurAmount + "px"'));
  -webkit-backdrop-filter: blur(v-bind('settingsStore.theme.blurAmount + "px"'));
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

.widget-mobile-header {
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.05);
}

.widget-mobile-content {
  padding: 16px;
}
</style>
