<template>
  <view class="path-view" :style="{ paddingTop: capsuleTopReservePx + 'px' }">
    <text class="page-title">实现路径</text>
    
    <view v-if="!selectedScript" class="empty-state glass-card">
      <text class="empty-icon">🗺️</text>
      <text class="empty-text">先生成剧本，方能洞察路径。</text>
      <button class="btn-secondary empty-btn" @click="goToScript">去生成剧本</button>
    </view>
    
    <view v-else-if="!currentPath" class="empty-state glass-card">
      <text class="empty-icon">🎯</text>
      <text class="empty-text">{{ pathEmptyText }}</text>
    </view>
    
    <view v-else class="path-content">
      <view class="target-card glass-card-gold">
        <text class="target-label">目标：{{ currentPath.title }}</text>
        <text class="target-summary">{{ (currentPath.description || currentPath.summary || currentPath.content || '').slice(0, 80) }}...</text>
      </view>
      
      <view class="timeline">
        <view class="timeline-line"></view>
        
        <view
          v-for="(step, index) in currentPath.steps"
          :key="index"
          class="timeline-item"
        >
          <view class="timeline-node" :class="step.done ? 'completed' : 'pending'"></view>
          
          <view class="step-card glass-card" :class="{ done: step.done }">
            <text class="step-phase">节点 {{ index + 1 }}</text>
            <text class="step-task">{{ step.task }}</text>
            <text class="step-desc">{{ step.desc }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { computed, ref, onMounted, onUnmounted, watch } from 'vue'
import { useAppStore } from '../../stores/app.js'
import { useTypewriterStream } from '../../composables/useTypewriterStream.js'
import { useMenuButtonSafeArea } from '../../composables/useMenuButtonSafeArea.js'
import * as lifePathService from '../../services/lifePath.js'
import { streamAiScene } from '../../services/aiRuntime.js'

const store = useAppStore()
const { capsuleTopReservePx } = useMenuButtonSafeArea({ extraTopPx: 10 })

const pathData = ref(null)
const pathGenerating = ref(false)
const pathWriter = useTypewriterStream({ interval: 32, step: 1 })

const selectedScript = computed(() => {
  return store.scripts.find(s => s.isSelected)
})

const currentPath = computed(() => {
  if (pathData.value) return pathData.value
  if (store.currentPath) return store.currentPath
  return null
})

const pathEmptyText = computed(() => {
  if (pathWriter.isWaiting.value) return '正在分析剧本，拆解可执行路径...'
  if (pathWriter.isStreaming.value || pathWriter.isDraining.value) return '正在生成路径节点...'
  return '等待开启人生导航...'
})

const buildStreamPath = (scriptId, title, output) => ({
  id: `stream-${scriptId}`,
  scriptId,
  title,
  description: output,
  steps: output.split('\n').filter(Boolean).slice(0, 6).map((line, index) => ({
    phase: `阶段${index + 1}`,
    task: line.replace(/^\d+[.、]\s*/, '').slice(0, 28),
    desc: line,
    content: line,
    done: index === 0
  })),
  progress: 8,
  status: 'active'
})

watch(() => pathWriter.visibleText.value, (text) => {
  if (!(pathGenerating.value || pathWriter.isStreaming.value || pathWriter.isDraining.value) || !selectedScript.value?.id || !text) return
  const title = selectedScript.value.title ? `${selectedScript.value.title} · 实现路径` : '我的实现路径'
  pathData.value = buildStreamPath(selectedScript.value.id, title, text)
})

const loadPath = async (scriptId) => {
  if (!scriptId) return
  try {
    const res = await lifePathService.getPathByScriptId(scriptId)
    pathData.value = res.data || await createPlaceholderPath(scriptId)
    store.setCurrentPath(pathData.value)
  } catch (error) {
    pathData.value = await createPlaceholderPath(scriptId)
    store.setCurrentPath(pathData.value)
  }
}

const createPlaceholderPath = async (scriptId) => {
  const script = selectedScript.value || {}
  const title = script.title ? `${script.title} · 实现路径` : '我的实现路径'
  let generatedText = ''
  pathGenerating.value = true
  pathWriter.reset()
  try {
    const streamRes = await streamAiScene({
      sceneCode: 'life_healing',
      inputs: {
        mode: 'path_generate',
        prompt: `请把下面的人生剧本拆解成现实中可执行的路径，按阶段输出。\n\n${script.content || script.summary || ''}`,
        script: script.content || script.summary || ''
      },
      onDelta: (_delta, output) => {
        generatedText = output
        pathWriter.push(output)
      },
      onDone: (_event, output) => {
        pathWriter.finish(output)
      },
      onError: (message) => {
        pathWriter.fail(message || '路径生成失败')
      }
    })
    generatedText = streamRes.output || generatedText
    pathWriter.finish(generatedText)
    await pathWriter.waitForDone()
  } catch (error) {
    pathWriter.fail(error?.message || '路径生成失败')
    generatedText = ''
  } finally {
    pathGenerating.value = false
  }
  const steps = [
    { phase: '阶段1', task: '整理目标', desc: '把剧本中的关键目标拆成可以执行的小目标。', content: '把剧本中的关键目标拆成可以执行的小目标。', done: true },
    { phase: '阶段2', task: '建立习惯', desc: '选择一个最小行动，每天稳定推进。', content: '选择一个最小行动，每天稳定推进。', done: false },
    { phase: '阶段3', task: '复盘迭代', desc: '每周回看进展，根据现实反馈调整路径。', content: '每周回看进展，根据现实反馈调整路径。', done: false }
  ]
  if (generatedText) {
    const generatedSteps = generatedText.split('\n').filter(Boolean).slice(0, 6).map((line, index) => ({
      phase: `阶段${index + 1}`,
      task: line.replace(/^\d+[.、]\s*/, '').slice(0, 28),
      desc: line,
      content: line,
      done: index === 0
    }))
    if (generatedSteps.length) {
      steps.splice(0, steps.length, ...generatedSteps)
    }
  }
  try {
    const res = await lifePathService.createPath({
      scriptId,
      title,
      description: generatedText || script.summary || '根据选中的人生剧本生成的占位实现路径，后续可接入AI生成更细的行动计划。',
      steps,
      progress: 8,
      status: 'active'
    })
    return lifePathService.transformToFrontendFormat(res.data)
  } catch (error) {
    return {
      id: `local-${scriptId}`,
      scriptId,
      title,
      description: script.summary || '占位实现路径',
      steps,
      progress: 8,
      status: 'active'
    }
  }
}

const goToScript = () => {
  uni.$emit('switchTab', 'script')
}

watch(selectedScript, (val) => {
  if (val?.id) {
    loadPath(val.id)
  } else {
    pathData.value = null
  }
})

onMounted(() => {
  if (selectedScript.value?.id) {
    loadPath(selectedScript.value.id)
  }
})

onUnmounted(() => {
  pathWriter.dispose()
})
</script>

<style scoped>
.path-view {
  display: flex;
  flex-direction: column;
  gap: 32rpx;
  min-height: 100%;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.page-title {
  font-size: 36rpx;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.9);
  margin-bottom: 8rpx;
  letter-spacing: 4rpx;
  font-family: 'Cinzel', 'Inter', serif;
}

.empty-state {
  padding: 120rpx 64rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32rpx;
}

.empty-icon {
  font-size: 80rpx;
  opacity: 0.3;
}

.empty-text {
  font-size: 24rpx;
  color: rgba(192, 132, 252, 0.5);
  font-style: italic;
  text-align: center;
  line-height: 1.6;
}

.empty-btn {
  font-size: 22rpx;
  padding: 18rpx 36rpx;
}

.path-content {
  display: flex;
  flex-direction: column;
  gap: 48rpx;
}

.target-card {
  padding: 40rpx;
  margin-bottom: 16rpx;
  /* 金色玻璃态 + 左侧紫色边框 */
  border-left: 4rpx solid #C084FC;
  box-shadow: inset 0 0 20rpx rgba(168, 85, 247, 0.05),
              0 4rpx 16rpx rgba(168, 85, 247, 0.1);
}

.target-label {
  display: block;
  font-size: 18rpx;
  color: #C084FC;
  font-weight: 600;
  letter-spacing: 4rpx;
  text-transform: uppercase;
  margin-bottom: 16rpx;
}

.target-summary {
  display: block;
  font-size: 28rpx;
  color: rgba(255, 255, 255, 0.9);
  line-height: 1.6;
}

.timeline {
  position: relative;
  padding-left: 60rpx;
  display: flex;
  flex-direction: column;
  gap: 48rpx;
}

.timeline-line {
  position: absolute;
  left: 30rpx;
  top: 30rpx;
  bottom: 30rpx;
  width: 4rpx;
  background: linear-gradient(180deg,
    rgba(168, 85, 247, 0.4) 0%,
    rgba(168, 85, 247, 0.2) 50%,
    rgba(168, 85, 247, 0.05) 100%
  );
  border-radius: 4rpx;
  box-shadow: 0 0 15px rgba(168, 85, 247, 0.2);
}

.timeline-item {
  position: relative;
}

.timeline-node {
  position: absolute;
  left: -46rpx;
  top: 24rpx;
  width: 48rpx;
  height: 48rpx;
  border-radius: 50%;
  background: linear-gradient(135deg, #A855F7 0%, #9333EA 100%);
  border: 4rpx solid #C084FC;
  /* 原型标准：节点发光 */
  box-shadow: 0 0 15px rgba(168, 85, 247, 0.4),
              inset 0 0 10rpx rgba(255, 255, 255, 0.2);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
}

.timeline-node.completed {
  animation: node-pulse 2s ease-in-out infinite;
}

@keyframes node-pulse {
  0%, 100% {
    box-shadow: 0 0 15px rgba(168, 85, 247, 0.4),
                inset 0 0 10rpx rgba(255, 255, 255, 0.2);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 25px rgba(168, 85, 247, 0.6),
                inset 0 0 15rpx rgba(255, 255, 255, 0.3);
    transform: scale(1.05);
  }
}

.timeline-node.pending {
  background: #0F071A;
  border-color: rgba(255, 255, 255, 0.1);
  box-shadow: 0 0 10px rgba(168, 85, 247, 0.1);
}

.step-card {
  padding: 32rpx;
  opacity: 0.6;
}

.step-card.done {
  opacity: 1;
  border-color: rgba(192, 132, 252, 0.3);
}

.step-phase {
  display: block;
  font-size: 18rpx;
  color: #C084FC;
  font-weight: 600;
  letter-spacing: 4rpx;
  margin-bottom: 12rpx;
}

.step-task {
  display: block;
  font-size: 30rpx;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 12rpx;
}

.step-desc {
  display: block;
  font-size: 22rpx;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.5;
}
</style>
