<template>
  <Transition name="panel">
    <div 
      v-if="show" 
      class="panel-overlay" 
      @mousedown.self="onOverlayMouseDown" 
      @mouseup.self="onOverlayMouseUp"
    >
      <div 
        class="panel" 
        :class="{ mobile: isMobile }"
        :style="{ width: panelWidth + 'px' }" 
        ref="panelRef" 
        @mousedown="overlayMouseDownTarget = false"
      >
        <!-- Ручка для изменения ширины -->
        <div 
          class="resize-handle"
          @mousedown="startResize"
        ></div>
        
        <div class="panel-header">
          <div class="header-content">
            <slot name="header"></slot>
          </div>
          <button class="btn-close" @click="handleClose">
            <i data-lucide="x"></i>
          </button>
        </div>

        <div class="panel-body">
          <slot></slot>
        </div>

        <div v-if="$slots.footer" class="panel-footer">
          <slot name="footer"></slot>
        </div>
      </div>
    </div>
  </Transition>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { useMobile } from '../../composables/useMobile'
import { useLucideIcons } from '../../composables/useLucideIcons'

const { isMobile } = useMobile()

useLucideIcons()

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  width: {
    type: Number,
    default: 600
  },
  minWidth: {
    type: Number,
    default: 500
  },
  maxWidth: {
    type: Number,
    default: 1000
  },
  resizable: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['close', 'update:show'])

const STORAGE_KEY = 'taskboard_panel_width'

const panelRef = ref(null)
const panelWidth = ref(getSavedWidth())
const isResizing = ref(false)
const overlayMouseDownTarget = ref(false)

// Получить сохранённую ширину из localStorage
function getSavedWidth() {
  const saved = localStorage.getItem(STORAGE_KEY)
  if (saved) {
    const width = parseInt(saved, 10)
    if (!isNaN(width)) return width
  }
  return props.width
}

// Сохранить ширину в localStorage
function saveWidth(width) {
  localStorage.setItem(STORAGE_KEY, String(width))
}

// Resize логика
const startResize = (e) => {
  if (!props.resizable) return
  isResizing.value = true
  document.addEventListener('mousemove', onResize)
  document.addEventListener('mouseup', stopResize)
  document.body.style.cursor = 'ew-resize'
  document.body.style.userSelect = 'none'
}

const onResize = (e) => {
  if (!isResizing.value) return
  const newWidth = window.innerWidth - e.clientX
  panelWidth.value = Math.min(props.maxWidth, Math.max(props.minWidth, newWidth))
}

const stopResize = () => {
  // Сохраняем ширину в localStorage
  saveWidth(panelWidth.value)
  
  setTimeout(() => {
    isResizing.value = false
  }, 100)
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
  document.body.style.cursor = ''
  document.body.style.userSelect = ''
}

// Закрытие по клику на overlay
const onOverlayMouseDown = () => {
  overlayMouseDownTarget.value = true
}

const onOverlayMouseUp = () => {
  if (overlayMouseDownTarget.value && !isResizing.value) {
    handleClose()
  }
  overlayMouseDownTarget.value = false
}

const handleClose = () => {
  emit('close')
  emit('update:show', false)
}

// Блокировка скролла body при открытии панели
const lockBodyScroll = () => {
  document.body.classList.add('panel-open')
}

const unlockBodyScroll = () => {
  document.body.classList.remove('panel-open')
}

// Принудительный reflow для iOS PWA - исправляет баг с safe-area при первом рендере
const forceReflow = () => {
  if (panelRef.value) {
    // Читаем offsetHeight чтобы вызвать reflow
    void panelRef.value.offsetHeight
  }
}

// Восстановление ширины при открытии (из localStorage или дефолтная)
watch(() => props.show, (newVal) => {
  if (newVal) {
    panelWidth.value = getSavedWidth()
    lockBodyScroll()
    // Два requestAnimationFrame для гарантированного reflow после рендера
    requestAnimationFrame(() => {
      requestAnimationFrame(forceReflow)
    })
  } else {
    unlockBodyScroll()
  }
})

onUnmounted(() => {
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
  unlockBodyScroll()
})
</script>

<style scoped>
.panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  /* Блокируем горизонтальные свайпы на мобильных */
  touch-action: pan-y pinch-zoom;
  overscroll-behavior: contain;
}

.panel {
  position: fixed;
  top: 0;
  right: 0;
  max-width: 100%;
  height: 100vh;
  height: 100dvh; /* Динамическая высота для iOS */
  background: #18181b;
  display: flex;
  flex-direction: column;
  box-shadow: -10px 0 40px rgba(0, 0, 0, 0.4);
}

.resize-handle {
  position: absolute;
  left: 0;
  top: 0;
  width: 6px;
  height: 100%;
  cursor: ew-resize;
  background: transparent;
  transition: background 0.15s;
  z-index: 10;
}

.resize-handle:hover,
.resize-handle:active {
  background: var(--accent);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 32px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.header-content {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
  min-width: 0;
}

.header-content :deep(h2) {
  font-size: 20px;
  font-weight: 500;
  margin: 0;
}

.header-content :deep(.header-title-block) {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.header-content :deep(.header-date) {
  font-size: 12px;
  color: var(--text-muted);
}

.header-content :deep(.header-tabs) {
  margin-left: auto;
}

.btn-close {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  transition: all 0.15s;
  flex-shrink: 0;
}

.btn-close i {
  width: 20px;
  height: 20px;
}

.btn-close:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-primary);
}

.panel-body {
  flex: 1;
  padding: 32px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.panel-body::-webkit-scrollbar {
  width: 6px;
}

.panel-body::-webkit-scrollbar-track {
  background: transparent;
}

.panel-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 3px;
}

.panel-body::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.25);
}

.panel-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 32px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

/* Transition — выезд справа для десктопа */
.panel-enter-active,
.panel-leave-active {
  transition: opacity 0.25s ease;
}

.panel-enter-active .panel,
.panel-leave-active .panel {
  transition: transform 0.25s ease;
}

.panel-enter-from,
.panel-leave-to {
  opacity: 0;
}

.panel-enter-from .panel,
.panel-leave-to .panel {
  transform: translateX(100%);
}

/* На мобильных убираем transform из анимации - он ломает layout в iOS PWA */
.panel-enter-from .panel.mobile,
.panel-leave-to .panel.mobile {
  transform: none;
}

/* ========== MOBILE: Fullscreen ========== */
/* height: 100% вместо 100dvh - потому что wrapper уже учитывает safe-area */
.panel.mobile {
  width: 100% !important;
  max-width: 100%;
  height: 100%; /* Занимаем всю высоту wrapper, не viewport */
  border-radius: 0;
  touch-action: pan-y pinch-zoom;
  overscroll-behavior: contain;
  /* Сплошной цвет вместо градиента */
  background: var(--bg-body);
}

.panel.mobile .resize-handle {
  display: none;
}

.panel.mobile .panel-header {
  padding: 16px;
}

.panel.mobile .panel-body {
  padding: 16px;
  min-height: 0;
  gap: 20px;
  overflow-y: auto;
}

.panel.mobile .panel-footer {
  padding: 16px;
  /* Safe area для iPhone home indicator */
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}

.panel.mobile .header-content :deep(h2) {
  font-size: 18px;
}
</style>
