<template>
  <!-- 分离窗口:纯内容,不渲染主布局 -->
  <div v-if="isDetached" class="df-detached-root">
    <slot name="detached" />
  </div>
  <!-- 主窗口:完整布局 -->
  <div v-else class="df-shell">
    <AppSidebar />

    <!-- ═══ Main (页面内容) ═══ -->
    <!-- 仅在 AI 面板可见且最大化时隐藏主内容;面板关闭时无论 maximized 状态如何都显示 -->
    <main class="df-main" v-show="!(aiStore.state.maximized && aiStore.state.panelOpen)">
      <slot />
    </main>

    <!-- ═══ AI Chat Panel ═══ -->
    <transition name="ai-slide">
      <div v-if="aiStore.state.panelOpen && !aiStore.state.detached" class="df-ai-panel" :style="panelStyle">
        <div v-show="!aiStore.state.maximized" class="ai-resize-handle" :class="{ active: resizing }" @mousedown="startResize"></div>
        <slot name="ai-panel" />
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAiStore } from '@/stores/ai'
import { useAppSettingsStore } from '@/stores/appSettings'
import AppSidebar from './AppSidebar.vue'

const props = defineProps<{
  isDetached: boolean
}>()

const aiStore = useAiStore()
const appSettings = useAppSettingsStore()

// ── 7a:路由路径+查询启动恢复(仅主窗口)──
// 持久化到 localStorage(轻量、同步、读早于 appSettings.loadAll 完成,避免闪烁)。
// 各列表页(Tasks/Ideas/...)的筛选恢复由各自 agent 读写各自 localStorage key;
// 此处只负责「上次所在页面 + query」级别的恢复(如 /tasks?status=done)。
// 分离窗口(ai-detached/file-explorer-detached/approval-popup)不参与:它们有专属
// 入口路由,且会被 watch 误覆盖主窗口记录。
const ROUTE_STORAGE_KEY = 'df-last-route'
// 这些路径不持久化(过渡/分离/弹窗/根跳转):避免分离窗口覆盖、避免 '/' redirect 噪音
const NON_PERSIST_PATHS = new Set(['/', '/ai-detached', '/file-explorer-detached', '/approval-popup'])

const route = useRoute()
const router = useRouter()

/** 写入当前 path + query 到 localStorage(忽略 NON_PERSIST 路径) */
function persistRoute(path: string, query: Record<string, string>) {
  if (props.isDetached || NON_PERSIST_PATHS.has(path)) return
  try {
    localStorage.setItem(ROUTE_STORAGE_KEY, JSON.stringify({ path, query }))
  } catch {
    /* 配额溢出/隐私模式,静默 */
  }
}

onMounted(() => {
  // 分离窗口不恢复(它们的入口路由由打开方指定)
  if (props.isDetached) return
  // 首屏若落在根 redirect('/') 或 ai-home,尝试恢复上次路由
  try {
    const raw = localStorage.getItem(ROUTE_STORAGE_KEY)
    if (!raw) return
    const saved = JSON.parse(raw) as { path?: string; query?: Record<string, string> }
    const targetPath = saved.path
    if (!targetPath || NON_PERSIST_PATHS.has(targetPath)) return
    // 仅在当前确实处于根/首页时恢复(避免覆盖用户深链接或刷新某具体页)
    if (route.path !== '/' && route.path !== '/ai-home') {
      // 用户已在某具体页:仅补持久化当前页,不抢断
      persistRoute(route.path, { ...route.query } as Record<string, string>)
      return
    }
    // 恢复:仅当目标路由存在(catch-all 会 redirect,这里 router.replace 自身已容错)
    const targetQuery = saved.query || {}
    // 防自循环:目标与当前位置完全一致则不 replace
    if (targetPath === route.path && Object.keys(targetQuery).length === 0) return
    router.replace({ path: targetPath, query: targetQuery })
  } catch {
    /* 解析失败:数据损坏,忽略(下次 watch 会覆写正确值) */
  }
})

// watch 路由变化:持久化最新 path + query(主窗口)
watch(
  () => route.path,
  (path) => persistRoute(path, { ...route.query } as Record<string, string>),
)
// query 变化(同 path 不同 query,如筛选)也要持久化
watch(
  () => route.query,
  (q) => persistRoute(route.path, { ...(q as Record<string, string>) }),
  { deep: true },
)

// ── AI 面板拖拽调宽 ──
// useSetting 监听 appSettings 缓存:loadAll 异步填充后会自动刷新 ref
const panelWidth = appSettings.useSetting<number>('df-ai-width', 500)
const resizing = ref(false)

// maximized=全宽(flex:1填充) | sidebar=固定宽
const panelStyle = computed(() => {
  if (aiStore.state.maximized) return { flex: '1', minWidth: '0' }
  return {
    width: panelWidth.value + 'px',
    minWidth: panelWidth.value + 'px',
    maxWidth: panelWidth.value + 'px',
  }
})

function startResize(e: MouseEvent) {
  e.preventDefault()
  resizing.value = true
  const startX = e.clientX
  const startWidth = panelWidth.value

  document.body.style.cursor = 'col-resize'
  document.body.style.userSelect = 'none'

  function onMouseMove(ev: MouseEvent) {
    const delta = startX - ev.clientX // 向左拖 = 增宽
    const newWidth = Math.max(320, Math.min(800, startWidth + delta))
    panelWidth.value = newWidth
  }

  function onMouseUp() {
    resizing.value = false
    document.body.style.cursor = ''
    document.body.style.userSelect = ''
    void appSettings.set('df-ai-width', panelWidth.value)
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
  }

  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
}
</script>

<style scoped>
.df-detached-root { width: 100vw; height: 100vh; overflow: hidden; background: var(--df-bg); }
.df-shell { display: flex; height: 100vh; width: 100vw; overflow: hidden; }

/* — Main — */
.df-main {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--df-bg);
  min-width: 0;
}

/* — AI Panel (全宽) — */
.df-ai-panel {
  position: relative;
  height: 100vh;
  overflow: hidden;
}

/* — AI Resize Handle — */
.ai-resize-handle {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  cursor: col-resize;
  z-index: 10;
  transition: background 0.15s;
}
.ai-resize-handle:hover,
.ai-resize-handle.active {
  background: var(--df-accent);
  opacity: 0.4;
}

/* — AI Slide Transition — */
.ai-slide-enter-active { transition: opacity 0.2s var(--df-ease); }
.ai-slide-leave-active { transition: opacity 0.15s var(--df-ease); }
.ai-slide-enter-from, .ai-slide-leave-to {
  opacity: 0;
}

/* ═══ Responsive ═══ */
@media (max-width: 768px) {
  .df-ai-panel { width: 100vw; min-width: 100vw; max-width: 100vw; position: absolute; right: 0; top: 0; z-index: 100; }
}
</style>
