<template>
  <v-dialog v-model="dialog" max-width="1400px" persistent scrollable>
    <template v-slot:activator="{ props }">
      <div class="t2i-template-editor-trigger">
        <v-btn
          v-bind="props"
          variant="tonal"
          color="primary"
          size="small"
          class="t2i-template-editor-button"
          :loading="loading"
        >
          <v-icon class="mr-2">mdi-code-tags</v-icon>
          {{ tm('t2iTemplateEditor.buttonText') }}
        </v-btn>
      </div>
    </template>
    
    <v-card class="t2i-template-editor">
      <v-card-title class="d-flex align-center justify-space-between">
        <span>{{ tm('t2iTemplateEditor.dialogTitle') }}</span>
        <v-spacer></v-spacer>
        <div class="d-flex align-center gap-2" style="width: 60%">
          <v-text-field
            v-if="isCreatingNew"
            v-model="editingName"
            :label="tm('t2iTemplateEditor.newTemplateNameLabel')"
            density="compact"
            hide-details
            variant="outlined"
            class="flex-grow-1"
            autofocus
            :rules="[v => !!v || tm('t2iTemplateEditor.nameRequired')]"
          ></v-text-field>
          <v-select
            v-else
            v-model="selectedTemplate"
            :items="templates"
            item-title="name"
            item-value="name"
            :label="tm('t2iTemplateEditor.selectTemplateLabel')"
            density="compact"
            hide-details
            variant="outlined"
            class="flex-grow-1"
            :loading="loading"
          >
            <template v-slot:item="{ props, item }">
              <v-list-item v-bind="props" :title="item.raw.name">
                <template v-slot:append>
                  <v-chip
                    v-if="item.raw.name === activeTemplate"
                    color="success"
                    variant="tonal"
                    size="small"
                    class="ml-2"
                  >
                    {{ tm('t2iTemplateEditor.applied') }}
                  </v-chip>
                  <v-btn
                    v-else
                    variant="text"
                    color="primary"
                    size="small"
                    class="ml-2"
                    @click.stop="setActiveTemplate(item.raw.name)"
                    :loading="applyLoading"
                  >
                    {{ tm('t2iTemplateEditor.apply') }}
                  </v-btn>
                </template>
              </v-list-item>
            </template>
          </v-select>
          <v-btn
            variant="text"
            icon
            @click="closeDialog"
          >
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </div>
      </v-card-title>

      <v-card-text class="pa-0">
        <v-row no-gutters style="height: 70vh;">
          <!-- 左侧编辑器 -->
          <v-col cols="6" class="d-flex flex-column">
            <v-toolbar density="compact" color="surface-variant">
              <v-toolbar-title class="text-subtitle-2">{{ tm('t2iTemplateEditor.templateEditor') }}</v-toolbar-title>
              <v-spacer></v-spacer>
              <div class="d-flex align-center pa-1" style="border: 1px solid rgba(0,0,0,0.1); border-radius: 8px;">
                <v-btn
                  variant="text"
                  size="small"
                  @click="newTemplate"
                  color="success"
                >
                  <v-icon left>mdi-plus</v-icon>
                  {{ tm('t2iTemplateEditor.new') }}
                </v-btn>
                <v-divider vertical class="mx-1"></v-divider>
                <v-btn
                  variant="text"
                  size="small"
                  @click="resetToDefault"
                  :loading="resetLoading"
                  color="warning"
                >
                  {{ tm('t2iTemplateEditor.resetBase') }}
                </v-btn>
                <v-btn
                  variant="text"
                  size="small"
                  @click="promptDelete"
                  color="error"
                  :disabled="isCreatingNew || selectedTemplate === 'base' || !selectedTemplate"
                >
                  {{ tm('t2iTemplateEditor.delete') }}
                </v-btn>
                <v-divider vertical class="mx-1"></v-divider>
                <v-btn
                  variant="text"
                  size="small"
                  @click="saveTemplate"
                  :loading="saveLoading"
                  color="primary"
                  :disabled="(isCreatingNew && !editingName) || (!isCreatingNew && !selectedTemplate)"
                >
                  {{ tm('t2iTemplateEditor.save') }}
                </v-btn>
              </div>
            </v-toolbar>
            <div class="flex-grow-1" style="border-right: 1px solid rgba(0,0,0,0.1);">
              <VueMonacoEditor
                v-model:value="templateContent"
                :theme="editorTheme"
                language="html"
                :options="editorOptions"
                style="height: 100%;"
              />
            </div>
          </v-col>

          <!-- 右侧预览 -->
          <v-col cols="6" class="d-flex flex-column">
            <v-toolbar density="compact" color="surface-variant">
              <v-toolbar-title class="text-subtitle-2">{{ tm('t2iTemplateEditor.livePreview') }}</v-toolbar-title>
              <v-spacer></v-spacer>
              <v-btn
                variant="text"
                size="small"
                @click="refreshPreview"
                :loading="previewLoading"
              >
                {{ tm('t2iTemplateEditor.refreshPreview') }}
              </v-btn>
            </v-toolbar>
            <div class="flex-grow-1 preview-container">
              <iframe
                ref="previewFrame"
                :srcdoc="previewContent"
                style="width: 100%; height: 100%; border: none; zoom: 0.6;"
              />
            </div>
          </v-col>
        </v-row>
      </v-card-text>

      <v-card-actions class="px-6 py-4">
        <v-row no-gutters class="align-center">
          <v-col>
            <div class="text-caption text-grey">
              <v-icon size="16" class="mr-1">mdi-information</v-icon>
              {{ tm('t2iTemplateEditor.syntaxHint') }}
            </div>
          </v-col>
          <v-col cols="auto">
            <v-btn
              variant="text"
              @click="closeDialog"
            >
              {{ t('core.common.cancel') }}
            </v-btn>
            <v-btn
              color="primary"
              variant="tonal"
              @click="promptApplyAndClose"
              :loading="saveLoading"
              :disabled="isCreatingNew || !selectedTemplate"
            >
              {{ tm('t2iTemplateEditor.saveAndApply') }}
            </v-btn>
          </v-col>
        </v-row>
      </v-card-actions>
    </v-card>

    <!-- 确认重置对话框 -->
    <v-dialog v-model="resetDialog" max-width="400px">
      <v-card>
        <v-card-title>{{ tm('t2iTemplateEditor.confirmReset') }}</v-card-title>
        <v-card-text>
          {{ tm('t2iTemplateEditor.confirmResetMessage') }}
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn text @click="resetDialog = false">{{ t('core.common.cancel') }}</v-btn>
          <v-btn color="warning" variant="tonal" @click="confirmReset" :loading="resetLoading">{{ tm('t2iTemplateEditor.confirmResetButton') }}</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- 删除确认对话框 -->
    <v-dialog v-model="deleteDialog" max-width="400px">
      <v-card>
        <v-card-title>{{ tm('t2iTemplateEditor.confirmDelete') }}</v-card-title>
        <v-card-text>
          {{ tm('t2iTemplateEditor.confirmDeleteMessage', { name: selectedTemplate }) }}
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn text @click="deleteDialog = false">{{ t('core.common.cancel') }}</v-btn>
          <v-btn color="error" variant="tonal" @click="confirmDelete" :loading="saveLoading">{{ tm('t2iTemplateEditor.confirmDeleteButton') }}</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- 保存并应用确认对话框 -->
    <v-dialog v-model="applyAndCloseDialog" max-width="500px">
      <v-card>
        <v-card-title>{{ tm('t2iTemplateEditor.confirmAction') }}</v-card-title>
        <v-card-text>
          {{ tm('t2iTemplateEditor.confirmApplyMessage', { name: selectedTemplate }) }}
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn text @click="applyAndCloseDialog = false">{{ t('core.common.cancel') }}</v-btn>
          <v-btn color="primary" variant="tonal" @click="confirmApplyAndClose" :loading="saveLoading">{{ t('core.common.confirm') }}</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

  </v-dialog>
</template>

<script setup>
import { ref, computed, nextTick, watch } from 'vue'
import { VueMonacoEditor } from '@guolao/vue-monaco-editor'
import { useI18n, useModuleI18n } from '@/i18n/composables'
import { useToast } from '@/utils/toast'
import { statsApi, t2iApi } from '@/api/v1'

const { t } = useI18n()
const { tm } = useModuleI18n('core.shared')
const toast = useToast()

// --- 响应式数据 ---
const dialog = ref(false)
const loading = ref(false) // 用于加载模板列表
const saveLoading = ref(false)
const resetLoading = ref(false)
const previewLoading = ref(false)
const applyLoading = ref(false)

// 模板管理
const templates = ref([])
const activeTemplate = ref('base')
const selectedTemplate = ref(null)
const editingName = ref('') // 用于新建模式下的名称输入
const templateContent = ref('')
const isCreatingNew = ref(false)

// 对话框状态
const resetDialog = ref(false)
const deleteDialog = ref(false)
const applyAndCloseDialog = ref(false)

const previewFrame = ref(null)

// --- 编辑器配置 ---
const editorTheme = computed(() => 'vs-light')
const editorOptions = {
  automaticLayout: true,
  fontSize: 12,
  lineNumbers: 'on',
  wordWrap: 'on',
  minimap: { enabled: false },
  scrollBeyondLastLine: false,
}

// --- 预览逻辑 ---
const previewVersion = ref('v4.0.0')
const syncPreviewVersion = async () => {
  try {
    const res = await statsApi.version()
    const rawVersion = res?.data?.data?.version || res?.data?.version
    if (rawVersion) {
      previewVersion.value = rawVersion.startsWith('v') ? rawVersion : `v${rawVersion}`
    }
  } catch (error) {
    console.warn('Failed to fetch version:', error)
  }
}

const previewData = computed(() => ({
  text: tm('t2iTemplateEditor.previewText') || '这是一个示例文本，用于预览模板效果。\n\n这里可以包含多行文本，支持换行和各种格式。',
  version: previewVersion.value
}))

const injectShikiRuntime = (content) => {
  if (content.includes('astrbot-t2i-shiki-runtime')) {
    return content
  }

  const runtimeScript = getShikiRuntimeScript()
  const headClose = content.search(/<\/head\s*>/i)
  if (headClose >= 0) {
    return `${content.slice(0, headClose)}  ${runtimeScript}\n${content.slice(headClose)}`
  }

  return `${runtimeScript}\n${content}`
}

const getShikiRuntimeScript = () => '<script id="astrbot-t2i-shiki-runtime" src="/t2i/shiki_runtime.iife.js"></scr' + 'ipt>'

const hasMarkdownSource = (content) => /<[^>]+\bid=["']markdown-source["']/i.test(content)

const insertMarkdownSource = (content) => {
  const sourceElement = '  <textarea id="markdown-source" hidden>{{ text | safe }}</textarea>\n'
  const markedScript = content.search(/^[ \t]*<script\s+src=["']https:\/\/cdn\.jsdelivr\.net\/npm\/marked\/marked\.min\.js["']><\/script>[ \t]*\r?\n?/im)
  if (markedScript >= 0) {
    return `${content.slice(0, markedScript)}${sourceElement}${content.slice(markedScript)}`
  }

  const bodyClose = content.search(/<\/body\s*>/i)
  if (bodyClose >= 0) {
    return `${content.slice(0, bodyClose)}${sourceElement}${content.slice(bodyClose)}`
  }

  return `${sourceElement}${content}`
}

const normalizeMarkdownSource = (content) => {
  let normalized = content.replace(
    /<script\s+id=["']markdown-source["']\s+type=["']text\/plain["']>\s*\{\{\s*text\s*\|\s*safe\s*\}\}\s*<\/script>/gi,
    '<textarea id="markdown-source" hidden>{{ text | safe }}</textarea>'
  )

  normalized = normalized.replace(
    /decodeBase64Utf8\("\{\{\s*text_base64\s*\}\}"\)/g,
    'document.getElementById("markdown-source").value'
  )
  normalized = normalized.replace(
    /document\.getElementById\(["']markdown-source["']\)\.textContent/g,
    'document.getElementById("markdown-source").value'
  )

  if (/\{\{\s*text_base64\s*\}\}/.test(normalized) && !hasMarkdownSource(normalized)) {
    normalized = insertMarkdownSource(normalized)
  }

  return normalized
}

const previewContent = computed(() => {
  try {
    let content = normalizeMarkdownSource(templateContent.value)
    content = content.replace(/\{\{\s*text\s*\|\s*safe\s*\}\}/g, () => previewData.value.text)
    content = content.replace(/\{\{\s*version\s*\}\}/g, () => previewData.value.version)
    let usedExistingShikiPlaceholder = false
    content = content.replace(/<script\b[^>]*>\s*\{\{\s*shiki_runtime\s*\|\s*safe\s*\}\}\s*<\/script>/gi, () => {
      usedExistingShikiPlaceholder = true
      return getShikiRuntimeScript()
    })
    content = content.replace(/\{\{\s*shiki_runtime\s*\|\s*safe\s*\}\}/g, () => {
      usedExistingShikiPlaceholder = true
      return getShikiRuntimeScript()
    })
    return usedExistingShikiPlaceholder ? content : injectShikiRuntime(content)
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error)
    return `<div style="color: red; padding: 20px;">模板渲染错误: ${errorMessage}</div>`
  }
})

// --- API 调用方法 ---
const loadInitialData = async () => {
  loading.value = true
  try {
    const [listRes, activeRes] = await Promise.all([
      t2iApi.listTemplates(),
      t2iApi.getActiveTemplate()
    ])

    if (listRes.data.status === 'ok') {
      templates.value = listRes.data.data
    } else {
      console.error('加载模板列表失败:', listRes.data.message)
    }

    if (activeRes.data.status === 'ok') {
      activeTemplate.value = activeRes.data.data.active_template
    } else {
      console.error('加载活动模板失败:', activeRes.data.message)
    }

    // 设置初始选中的模板
    if (templates.value.length > 0) {
      selectedTemplate.value = activeTemplate.value
    }

  } catch (error) {
    console.error('加载初始数据失败:', error)
  } finally {
    loading.value = false
  }
}

const loadTemplateContent = async (name) => {
  if (!name) return
  previewLoading.value = true
  try {
    const response = await t2iApi.getTemplate(name)
    if (response.data.status === 'ok') {
      templateContent.value = response.data.data.content
    } else {
      console.error(`加载模板 '${name}' 失败:`, response.data.message)
    }
  } catch (error) {
    console.error(`加载模板 '${name}' 失败:`, error)
  } finally {
    previewLoading.value = false
  }
}

const saveTemplate = async () => {
  saveLoading.value = true
  try {
    if (isCreatingNew.value) {
      // --- 创建新模板 ---
      if (!editingName.value) return
      const response = await t2iApi.createTemplate({
        name: editingName.value,
        content: templateContent.value
      })
      await loadInitialData() // 重新加载所有数据
      selectedTemplate.value = response.data.data.name
      isCreatingNew.value = false
    } else {
      // --- 更新现有模板 ---
      if (!selectedTemplate.value) return
      await t2iApi.updateTemplate(selectedTemplate.value, templateContent.value)
    }
  } catch (error) {
    const msg = error?.response?.data?.message || error?.message || String(error)
    console.error('保存模板失败:', msg)
    toast.error(msg)
  } finally {
    saveLoading.value = false
  }
}

const setActiveTemplate = async (name) => {
  applyLoading.value = true
  try {
    await t2iApi.setActiveTemplate(name)
    activeTemplate.value = name
  } catch (error) {
    const msg = error?.response?.data?.message || error?.message || String(error)
    console.error(`应用模板 '${name}' 失败:`, msg)
    toast.error(msg)
  } finally {
    applyLoading.value = false
  }
}

const confirmDelete = async () => {
  if (!selectedTemplate.value || selectedTemplate.value === 'base') return
  saveLoading.value = true
  try {
    const nameToDelete = selectedTemplate.value
    await t2iApi.deleteTemplate(nameToDelete)
    deleteDialog.value = false

    // 如果删除的是当前活动模板，则将活动模板重置为base
    if (activeTemplate.value === nameToDelete) {
        await setActiveTemplate('base')
    }
    await loadInitialData()
    selectedTemplate.value = 'base'
  } catch (error) {
    const msg = error?.response?.data?.message || error?.message || String(error)
    console.error(`删除模板失败:`, msg)
    toast.error(msg)
  } finally {
    saveLoading.value = false
  }
}

const confirmReset = async () => {
  resetLoading.value = true
  try {
    await t2iApi.resetDefaultTemplate()
    resetDialog.value = false
    if (selectedTemplate.value === 'base') {
      await loadTemplateContent('base')
    }
    if (activeTemplate.value !== 'base') {
        await setActiveTemplate('base')
    }
  } catch (error) {
    const msg = error?.response?.data?.message || error?.message || String(error)
    console.error('重置模板失败:', msg)
    toast.error(msg)
  } finally {
    resetLoading.value = false
  }
}

// --- UI 交互方法 ---

const resetToDefault = () => {
  resetDialog.value = true
}

const newTemplate = () => {
  isCreatingNew.value = true
  selectedTemplate.value = null
  editingName.value = ''
  templateContent.value = `<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>New Template</title>
</head>
<body>
  <!-- 从这里开始编辑 -->
  <article>{{ text | safe }}</article>
</body>
</html>
`
}

const promptDelete = () => {
  if (selectedTemplate.value && selectedTemplate.value !== 'base') {
    deleteDialog.value = true
  }
}

const promptApplyAndClose = () => {
  if (!isCreatingNew.value && selectedTemplate.value) {
    applyAndCloseDialog.value = true
  }
}

const confirmApplyAndClose = async () => {
  if (isCreatingNew.value) return
  
  await saveTemplate()
  await setActiveTemplate(selectedTemplate.value)
  applyAndCloseDialog.value = false
  closeDialog()
}

const refreshPreview = () => {
  previewLoading.value = true
  syncPreviewVersion()
  nextTick(() => {
    if (previewFrame.value) {
      previewFrame.value.contentWindow.location.reload()
    }
    setTimeout(() => previewLoading.value = false, 500)
  })
}

const closeDialog = () => {
  dialog.value = false
}

// --- 监听器和生命周期 ---

watch(dialog, (newVal) => {
  if (newVal) {
    syncPreviewVersion()
    loadInitialData()
  } else {
    // 关闭时重置状态
    selectedTemplate.value = null
    templateContent.value = ''
    isCreatingNew.value = false
  }
})

watch(selectedTemplate, (newName) => {
  if (newName) {
    isCreatingNew.value = false
    loadTemplateContent(newName)
  }
})

defineExpose({
  openDialog: () => {
    dialog.value = true
  }
})
</script>

<style scoped>
.t2i-template-editor-trigger {
  display: flex;
  justify-content: flex-end;
  width: 100%;
}

.t2i-template-editor-button {
  min-height: 36px;
  border-radius: 10px;
  font-size: 0.86rem;
  font-weight: 650;
}

.preview-container {
  background-color: #f5f5f5;
  position: relative;
}

.preview-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: 
    linear-gradient(45deg, #ccc 25%, transparent 25%), 
    linear-gradient(-45deg, #ccc 25%, transparent 25%), 
    linear-gradient(45deg, transparent 75%, #ccc 75%), 
    linear-gradient(-45deg, transparent 75%, #ccc 75%);
  background-size: 20px 20px;
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
  opacity: 0.1;
  pointer-events: none;
}

code {
  background-color: rgba(0,0,0,0.05);
  padding: 2px 4px;
  border-radius: 3px;
  font-size: 0.875em;
}
</style>

<style>
.v-theme--PurpleThemeDark .t2i-template-editor .preview-container {
  background-color: rgb(var(--v-theme-surface));
}
</style>
