<template>
  <div class="w-full h-[calc(100vh-8rem)] flex flex-col animate-reveal">
    <!-- Top Bar -->
    <div class="flex items-center justify-between mb-4 shrink-0 gap-3">
      <h1 class="text-xl md:text-2xl font-serif italic text-white truncate">
        {{ isEditing ? '编辑代码片段' : '新建代码片段' }}
      </h1>
      <div class="flex gap-2 md:gap-3 shrink-0">
        <button type="button" class="admin-btn-secondary text-sm" @click="handleCancel">
          取消
        </button>
        <button type="button" class="admin-btn-primary text-sm" @click="handleSubmit" :disabled="isSubmitting">
          {{ isSubmitting ? '提交中...' : (isEditing ? '更新' : '创建') }}
        </button>
      </div>
    </div>

    <form @submit.prevent="handleSubmit" class="flex-1 flex flex-col lg:flex-row gap-4 lg:gap-6 overflow-hidden min-h-0">
      <!-- Left: Code / Description tabs -->
      <div class="flex-1 flex flex-col min-w-0 min-h-[45vh] lg:min-h-0 h-full">
        <div class="admin-card flex-1 flex flex-col overflow-hidden border border-white/10 min-h-0">
          <div class="flex border-b border-white/10 shrink-0">
            <button
              v-for="tab in editorTabs"
              :key="tab.id"
              type="button"
              class="flex-1 px-4 py-2.5 text-xs font-mono transition-colors"
              :class="editorTab === tab.id
                ? 'text-art-accent bg-white/5 border-b-2 border-art-accent'
                : 'text-art-muted hover:text-white'"
              @click="editorTab = tab.id"
            >
              {{ tab.label }}
            </button>
          </div>

          <div v-show="editorTab === 'code'" class="flex-1 flex flex-col min-h-0 focus-within:border-art-accent/50">
            <MdEditor
              v-model="form.code"
              theme="dark"
              :preview="false"
              placeholder="请输入代码..."
              class="custom-md-editor flex-1"
            />
          </div>

          <div
            v-show="editorTab === 'description'"
            class="flex-1 flex flex-col min-h-0"
            @paste="handleVideoPaste"
          >
            <MdEditor
              ref="descEditorRef"
              v-model="form.description"
              theme="dark"
              :preview="true"
              placeholder="支持 Markdown，可上传图片、粘贴或拖拽视频..."
              class="custom-md-editor desc-md-editor flex-1"
              @onUploadImg="handleUploadImg"
              @onDrop="handleEditorDrop"
            />
          </div>
        </div>
        <div class="error-message mt-1" v-if="errors.code && editorTab === 'code'">{{ errors.code }}</div>
      </div>

      <!-- Right: Meta & Settings -->
      <div class="w-full lg:w-80 shrink-0 overflow-y-auto custom-scrollbar min-h-0 lg:max-h-full">
        <div class="admin-card p-5 md:p-6 space-y-5">
          <h3 class="text-sm font-medium text-white border-b border-white/5 pb-3 flex items-center gap-2">
            <span class="text-art-accent">⚙</span> 片段配置
          </h3>

          <div class="space-y-2">
            <label for="title" class="block text-xs font-medium text-art-muted uppercase tracking-wider">标题</label>
            <input
              type="text"
              id="title"
              v-model="form.title"
              class="admin-input"
              placeholder="请输入代码片段标题"
              required
            />
            <div class="error-message" v-if="errors.title">{{ errors.title }}</div>
          </div>

          <div class="space-y-2">
            <label class="block text-xs font-medium text-art-muted uppercase tracking-wider">类型</label>
            <CustomSelect
              v-model.number="form.codeTypeId"
              :options="codeTypeOptions"
              placeholder="请选择代码类型"
            />
            <div class="error-message" v-if="errors.codeTypeId">{{ errors.codeTypeId }}</div>
          </div>

          <div class="space-y-2">
            <label class="block text-xs font-medium text-art-muted uppercase tracking-wider">
              关联文章 <span class="normal-case text-art-muted/70">(可多选)</span>
            </label>
            <input
              v-model="postSearch"
              type="text"
              placeholder="搜索文章标题..."
              class="admin-input text-sm"
            />
            <div class="post-chip-list">
              <button
                v-for="p in filteredPosts"
                :key="p.id"
                type="button"
                class="post-chip"
                :class="{ 'post-chip--active': form.postIds.includes(p.id) }"
                @click="togglePost(p.id)"
              >
                {{ p.title }}
              </button>
              <div v-if="filteredPosts.length === 0" class="text-xs text-art-muted italic py-2">
                暂无匹配文章
              </div>
            </div>
          </div>
        </div>
      </div>
    </form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { MdEditor } from 'md-editor-v3'
import type { ExposeParam } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'

import { useToast } from '../../composables/useToast'
import { useMdMediaUpload } from '../../composables/useMdMediaUpload'
import { createSnippet, updateSnippet, fetchSnippet, getAdminCodeTypes, getAdminPosts, Post } from '../../services/api'
import CustomSelect from '../../components/CustomSelect.vue'

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

const descEditorRef = ref<ExposeParam>()
const { handleUploadImg, handleEditorDrop, handleVideoPaste } = useMdMediaUpload(descEditorRef)

const editorTab = ref<'code' | 'description'>('code')
const editorTabs = [
  { id: 'code' as const, label: '代码' },
  { id: 'description' as const, label: '备注' },
]

const isSubmitting = ref(false)
const isEditing = computed(() => !!route.params.id)
const errors = reactive<Record<string, string>>({})

const form = reactive({
  title: '',
  code: '',
  codeTypeId: 0,
  description: '',
  postIds: [] as number[]
})

const codeTypeOptions = ref<{ value: number; label: string }[]>([])
const adminPosts = ref<Post[]>([])
const postSearch = ref('')

const filteredPosts = computed(() => {
  const q = postSearch.value.trim().toLowerCase()
  if (!q) return adminPosts.value
  return adminPosts.value.filter(p => p.title.toLowerCase().includes(q))
})

const togglePost = (postId: number) => {
  const idx = form.postIds.indexOf(postId)
  if (idx === -1) {
    form.postIds.push(postId)
  } else {
    form.postIds.splice(idx, 1)
  }
}

const validateForm = (): boolean => {
  Object.keys(errors).forEach(key => delete errors[key])
  let isValid = true

  if (!form.title.trim()) {
    errors.title = '代码片段标题不能为空'
    isValid = false
  }
  if (!form.codeTypeId) {
    errors.codeTypeId = '请选择代码类型'
    isValid = false
  }
  if (!form.code.trim()) {
    errors.code = '代码内容不能为空'
    isValid = false
  }
  return isValid
}

const handleSubmit = async () => {
  if (!validateForm()) return

  isSubmitting.value = true
  try {
    if (isEditing.value) {
      await updateSnippet(route.params.id as string, form)
      toast.success('代码片段更新成功')
    } else {
      const result = await createSnippet(form)
      toast.success('代码片段创建成功')
      if (result.id) {
        router.push(`/admin/snippets/${result.id}/edit`)
        return
      }
    }
    router.push('/admin/snippets')
  } catch (error: any) {
    console.error('Error submitting form:', error)
    toast.error(error.message || (isEditing.value ? '更新代码片段失败' : '创建代码片段失败'))
  } finally {
    isSubmitting.value = false
  }
}

const handleCancel = () => {
  router.push('/admin/snippets')
}

onMounted(async () => {
  try {
    const [types, postsRes] = await Promise.all([
      getAdminCodeTypes(),
      getAdminPosts(1, 200)
    ])
    codeTypeOptions.value = types.map(t => ({ value: t.id, label: `${t.name} (${t.category === 0 ? '前端' : t.category === 1 ? '后端' : '其他'})` }))
    adminPosts.value = postsRes.list || []
  } catch (error) {
    console.error('Failed to load form data:', error)
  }

  if (isEditing.value) {
    try {
      const snippetId = route.params.id as string
      const snippet = await fetchSnippet(snippetId)
      form.title = snippet.title
      form.code = snippet.code
      form.codeTypeId = snippet.codeTypeId || snippet.codeType?.id || 0
      form.description = snippet.description || ''
      form.postIds = snippet.posts?.map(p => p.id) || []
    } catch (error: any) {
      console.error('Failed to fetch snippet data:', error)
      toast.error('加载代码片段数据失败: ' + (error.message || '未知错误'))
    }
  }
})
</script>

<style scoped>
.error-message {
  color: #ef4444;
  font-size: 0.75rem;
  margin-top: 0.25rem;
}

.editor-wrapper {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.5rem;
  overflow: hidden;
}

:deep(.custom-md-editor) {
  background-color: transparent !important;
  --md-bk-color: transparent !important;
  --md-color: white !important;
  --md-border-color: transparent !important;
  height: 100% !important;
  min-height: 280px;
}

:deep(.desc-md-editor) {
  height: 100% !important;
  min-height: 280px;
}

.post-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-height: 2.5rem;
  padding: 0.75rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.5rem;
  max-height: 160px;
  overflow-y: auto;
}

.post-chip {
  padding: 0.35rem 0.75rem;
  font-size: 0.75rem;
  border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  transition: all 0.2s;
  text-align: left;
}

.post-chip:hover {
  border-color: rgba(255, 255, 255, 0.3);
  color: white;
}

.post-chip--active {
  background: rgba(212, 179, 131, 0.15);
  border-color: #d4b383;
  color: #d4b383;
}

:deep(.md-editor-toolbar-wrapper) {
  background-color: rgba(0, 0, 0, 0.2) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
}

:deep(.md-editor-content) {
  background-color: transparent !important;
}

:deep(.md-editor-footer) {
  background-color: rgba(0, 0, 0, 0.2) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.1) !important;
}
</style>
