<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import TranslateResultPanel from './TranslateResultPanel.vue'
import { api, type TranslateResult } from '../api/request'
import { useDraggableFab } from '../composables/useDraggableFab'
import { useTranslateFab } from '../composables/useTranslateFab'

const route = useRoute()
const { open, toggleFab, closeFab } = useTranslateFab()
const { wrapStyle, dragging, onFabPointerDown, consumeDragClick } = useDraggableFab(
  'wordloop-fab-translate',
  () => ({
    x: 16,
    y: Math.round((window.innerHeight - 64) / 2 - 28),
  })
)

const input = ref('')
const result = ref<TranslateResult | null>(null)
const message = ref('')
const messageType = ref<'success' | 'error'>('success')
const loading = ref(false)
const adding = ref(false)
const inputRef = ref<HTMLInputElement | null>(null)

function resetState() {
  input.value = ''
  result.value = null
  message.value = ''
  loading.value = false
  adding.value = false
}

function handleToggle() {
  if (consumeDragClick()) return
  toggleFab()
}

async function handleTranslate() {
  const text = input.value.trim()
  if (!text || loading.value) return
  loading.value = true
  message.value = ''
  result.value = null
  try {
    const { data } = await api.translate(text)
    result.value = data
  } catch (e: unknown) {
    const err = e as { response?: { data?: { detail?: string } } }
    message.value = err.response?.data?.detail || '翻译失败'
    messageType.value = 'error'
  } finally {
    loading.value = false
  }
}

async function addToLibrary() {
  if (!result.value || adding.value || !result.value.target_text.trim()) return
  adding.value = true
  message.value = ''
  try {
    await api.createWord({
      source_text: result.value.source_text,
      target_text: result.value.target_text.trim(),
      source_lang: result.value.source_lang,
      target_lang: result.value.target_lang,
      phonetic: result.value.phonetic,
      example_en: result.value.example_en,
      example_cn: result.value.example_cn,
    })
    message.value = '已加入单词库 ✅'
    messageType.value = 'success'
  } catch (e: unknown) {
    const err = e as { response?: { data?: { detail?: string } } }
    message.value = err.response?.data?.detail || '添加失败'
    messageType.value = 'error'
  } finally {
    adding.value = false
  }
}

function onInputKeydown(e: KeyboardEvent) {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault()
    handleTranslate()
  }
}

function close() {
  closeFab()
}

watch(open, async (isOpen) => {
  if (isOpen) {
    await nextTick()
    inputRef.value?.focus()
  } else {
    resetState()
  }
})

watch(
  () => route.path,
  () => {
    if (open.value) closeFab()
  }
)
</script>

<template>
  <div class="translate-fab-wrap" :style="wrapStyle">
    <div v-if="open" class="translate-fab-backdrop" @click="close" />

    <transition name="translate-panel">
      <div v-if="open" class="translate-fab-panel" role="dialog" aria-label="快速翻译">
        <div class="translate-input-row">
          <input
            ref="inputRef"
            v-model="input"
            type="text"
            class="input translate-input"
            placeholder="输入中文或英文，回车翻译"
            @keydown="onInputKeydown"
          />
          <button
            type="button"
            class="btn btn-primary translate-btn"
            :disabled="loading || !input.trim()"
            @click="handleTranslate"
          >
            {{ loading ? '…' : '翻译' }}
          </button>
        </div>

        <div v-if="message" :class="['message', messageType]">{{ message }}</div>

        <div v-if="result" class="translate-result">
          <TranslateResultPanel v-model="result" compact :adding="adding" @add="addToLibrary" />
        </div>
      </div>
    </transition>

    <button
      type="button"
      class="translate-fab-btn"
      :class="{ open, dragging }"
      aria-label="快速翻译"
      :aria-expanded="open"
      @pointerdown="onFabPointerDown"
      @click="handleToggle"
    >
      <span class="fab-icon">{{ open ? '×' : '🔤' }}</span>
      <span class="fab-label">翻译</span>
    </button>
  </div>
</template>

<style scoped>
.translate-fab-wrap {
  position: fixed;
  z-index: 110;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  gap: 10px;
}

.translate-fab-backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(15, 23, 42, 0.25);
}

.translate-fab-panel {
  width: min(calc(100vw - 96px), 320px);
  padding: 12px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 8px 28px rgba(79, 110, 247, 0.2);
  border: 1px solid var(--border);
}

.translate-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.translate-input {
  flex: 1;
  min-width: 0;
  padding: 9px 12px;
  font-family: inherit;
  font-size: 14px;
}

.translate-btn {
  flex-shrink: 0;
  width: auto;
  padding: 8px 12px;
  font-size: 13px;
  line-height: 1.2;
  white-space: nowrap;
}

.message {
  margin-top: 8px;
  margin-bottom: 0;
  font-size: 13px;
  padding: 8px 10px;
}

.translate-result {
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.translate-fab-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border: none;
  border-radius: 50%;
  background: #fff;
  color: var(--primary);
  border: 2px solid var(--primary);
  box-shadow: 0 4px 16px rgba(79, 110, 247, 0.25);
  touch-action: none;
  cursor: grab;
  transition: transform 0.15s, box-shadow 0.15s, background 0.15s;
}

.translate-fab-btn:hover:not(.dragging) {
  transform: scale(1.04);
}

.translate-fab-btn.dragging {
  cursor: grabbing;
  transform: scale(1.02);
  box-shadow: 0 6px 20px rgba(79, 110, 247, 0.35);
}

.translate-fab-btn.open {
  background: var(--primary);
  color: #fff;
}

.fab-icon {
  font-size: 22px;
  line-height: 1;
}

.fab-label {
  font-size: 10px;
  font-weight: 700;
  margin-top: 2px;
}

.translate-panel-enter-active,
.translate-panel-leave-active {
  transition: opacity 0.15s, transform 0.15s;
}

.translate-panel-enter-from,
.translate-panel-leave-to {
  opacity: 0;
  transform: translateX(-8px);
}
</style>
