<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useViewerStore } from '@/stores/viewer'
import { getRenderService } from '@/services/renderService'
import { getPartsTreeService } from '@/services/partsTreeService'
import { getExplodeService } from '@/services/explodeService'
import { captureFullScreenshot } from '@/services/screenshotService'

import ToolbarButton from './ToolbarButton.vue'
import RenderModeSelector from './RenderModeSelector.vue'
import ExplodePopup from './ExplodePopup.vue'
import SectionPopup from './SectionPopup.vue'
import RenderPopup from './RenderPopup.vue'

const viewerStore = useViewerStore()

// Active popup state
const activePopup = ref<'explode' | 'section' | 'render' | null>(null)

// Screenshot state
const isCapturing = ref(false)
const showPreview = ref(false)
const previewUrl = ref<string | null>(null)
const screenshotBlob = ref<Blob | null>(null)

// Explode animation state
const isExplodeAnimating = ref(false)

// Computed states
const edgesEnabled = computed(() => viewerStore.renderSettings.edgesEnabled)
const autoColorEnabled = computed(() => viewerStore.renderSettings.autoColorEnabled)
const hasActiveCrossSection = computed(() =>
  viewerStore.crossSection.x.enabled ||
  viewerStore.crossSection.y.enabled ||
  viewerStore.crossSection.z.enabled
)
const isExploded = computed(() => viewerStore.explosionFactor > 0)

// Watch edge line toggle
watch(
  () => viewerStore.renderSettings.edgesEnabled,
  (enabled) => {
    const renderService = getRenderService()
    if (renderService.isInitialized()) {
      renderService.setEdgesEnabled(enabled)
      viewerStore.forceRender()
    }
  }
)

// Watch auto-color changes
watch(
  () => viewerStore.renderSettings.autoColorEnabled,
  (enabled) => {
    const service = getPartsTreeService()
    if (enabled) {
      service.applyAutoColors()
    } else {
      service.resetToOriginalColors()
    }
    viewerStore.forceRender()
  }
)

function togglePopup(popup: 'explode' | 'section' | 'render') {
  activePopup.value = activePopup.value === popup ? null : popup
}

function closePopup() {
  activePopup.value = null
}

function toggleEdges() {
  viewerStore.setEdgesEnabled(!edgesEnabled.value)
}

function toggleAutoColor() {
  viewerStore.setAutoColorEnabled(!autoColorEnabled.value)
}

function handleExplodeClick() {
  // Single click triggers animation
  const service = getExplodeService()
  if (!service.isInitialized() || service.getPartsCount() < 2) {
    togglePopup('explode')
    return
  }

  const currentFactor = viewerStore.explosionFactor
  const targetFactor = currentFactor <= 50 ? 100 : 0

  isExplodeAnimating.value = true
  service.animateExplosion(targetFactor, 800, () => {
    viewerStore.setExplosionFactor(targetFactor)
    isExplodeAnimating.value = false
  })
}

async function captureScreenshot() {
  if (!viewerStore.renderer || !viewerStore.scene || !viewerStore.camera) {
    return
  }

  isCapturing.value = true

  try {
    const blob = await captureFullScreenshot(
      viewerStore.renderer,
      viewerStore.scene,
      viewerStore.camera
    )

    screenshotBlob.value = blob
    previewUrl.value = URL.createObjectURL(blob)
    showPreview.value = true
  } catch (error) {
    console.error('Failed to capture screenshot:', error)
  } finally {
    isCapturing.value = false
  }
}

function downloadScreenshot() {
  if (!screenshotBlob.value) return

  const now = new Date()
  const timestamp = now.toISOString().replace(/[-:T]/g, '').slice(0, 14)
  const filename = `screenshot_${timestamp}.png`

  const url = URL.createObjectURL(screenshotBlob.value)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)

  closePreview()
}

function closePreview() {
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value)
  }
  showPreview.value = false
  previewUrl.value = null
  screenshotBlob.value = null
}

function handleKeydown(e: KeyboardEvent) {
  if (e.key === 'Escape') {
    if (showPreview.value) {
      closePreview()
    } else if (activePopup.value) {
      closePopup()
    }
  }
}

function handleOverlayClick(e: MouseEvent) {
  if ((e.target as HTMLElement).classList.contains('preview-overlay')) {
    closePreview()
  }
}

onMounted(() => {
  window.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeydown)
  if (previewUrl.value) {
    URL.revokeObjectURL(previewUrl.value)
  }
})
</script>

<template>
  <div v-if="viewerStore.model" class="floating-toolbar">
    <!-- Render Mode Selector -->
    <RenderModeSelector />

    <div class="toolbar-divider"></div>

    <!-- Edge Lines Toggle -->
    <ToolbarButton
      :active="edgesEnabled"
      title="边缘线"
      @click="toggleEdges"
    >
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
        <polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
        <line x1="12" y1="22.08" x2="12" y2="12"/>
      </svg>
    </ToolbarButton>

    <!-- Auto Color Toggle -->
    <ToolbarButton
      :active="autoColorEnabled"
      title="自动着色"
      @click="toggleAutoColor"
    >
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <rect x="3" y="3" width="7" height="7" rx="1"/>
        <rect x="14" y="3" width="7" height="7" rx="1"/>
        <rect x="14" y="14" width="7" height="7" rx="1"/>
        <rect x="3" y="14" width="7" height="7" rx="1"/>
      </svg>
    </ToolbarButton>

    <div class="toolbar-divider"></div>

    <!-- Explode -->
    <div class="toolbar-item">
      <ToolbarButton
        :active="isExploded"
        :disabled="isExplodeAnimating"
        title="爆炸图 (单击动画，右键设置)"
        @click="handleExplodeClick"
        @contextmenu.prevent="togglePopup('explode')"
      >
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M12 2L8 6H4v4l-4 4 4 4v4h4l4 4 4-4h4v-4l4-4-4-4V6h-4L12 2z"/>
          <circle cx="12" cy="12" r="3"/>
        </svg>
      </ToolbarButton>
      <ExplodePopup
        :show="activePopup === 'explode'"
        @close="closePopup"
      />
    </div>

    <!-- Cross Section -->
    <div class="toolbar-item">
      <ToolbarButton
        :active="hasActiveCrossSection"
        title="剖面"
        @click="togglePopup('section')"
      >
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="12" r="10"/>
          <line x1="12" y1="2" x2="12" y2="22"/>
        </svg>
      </ToolbarButton>
      <SectionPopup
        :show="activePopup === 'section'"
        @close="closePopup"
      />
    </div>

    <div class="toolbar-divider"></div>

    <!-- Render Settings -->
    <div class="toolbar-item">
      <ToolbarButton
        title="渲染设置"
        @click="togglePopup('render')"
      >
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="12" r="3"/>
          <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
        </svg>
      </ToolbarButton>
      <RenderPopup
        :show="activePopup === 'render'"
        @close="closePopup"
      />
    </div>

    <!-- Screenshot -->
    <ToolbarButton
      :disabled="isCapturing"
      title="截图"
      @click="captureScreenshot"
    >
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
        <circle cx="12" cy="13" r="4"/>
      </svg>
    </ToolbarButton>
  </div>

  <!-- Screenshot Preview Modal -->
  <Teleport to="body">
    <div
      v-if="showPreview"
      class="preview-overlay"
      @click="handleOverlayClick"
    >
      <div class="preview-modal">
        <div class="preview-image-container">
          <img
            v-if="previewUrl"
            :src="previewUrl"
            alt="Screenshot preview"
            class="preview-image"
          />
        </div>
        <div class="preview-actions">
          <button class="btn-download" @click="downloadScreenshot">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
              <polyline points="7 10 12 15 17 10"/>
              <line x1="12" y1="15" x2="12" y2="3"/>
            </svg>
            下载
          </button>
          <button class="btn-cancel" @click="closePreview">
            取消
          </button>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<style scoped>
.floating-toolbar {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--panel-overlay-bg);
  backdrop-filter: blur(var(--panel-backdrop-blur));
  -webkit-backdrop-filter: blur(var(--panel-backdrop-blur));
  border-radius: var(--radius-xl);
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-lg);
  z-index: 30;
}

.toolbar-divider {
  width: 1px;
  height: 24px;
  background: var(--border-color);
  margin: 0 4px;
}

.toolbar-item {
  position: relative;
}

/* Screenshot Preview Styles */
.preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  backdrop-filter: blur(4px);
  animation: fade-in 0.2s ease;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.preview-modal {
  background: var(--bg-primary);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  max-width: 90vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: scale-in 0.2s ease;
}

@keyframes scale-in {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.preview-image-container {
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-secondary);
}

.preview-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

.preview-actions {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4);
  justify-content: center;
  border-top: 1px solid var(--border-color);
}

.btn-download,
.btn-cancel {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 500;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-download {
  background: var(--primary-color);
  color: white;
}

.btn-download:hover {
  background: var(--primary-hover);
  transform: translateY(-1px);
}

.btn-download .icon {
  width: 16px;
  height: 16px;
}

.btn-cancel {
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  border: 1px solid var(--border-color);
}

.btn-cancel:hover {
  background: var(--bg-sunken);
  color: var(--text-primary);
}
</style>
