<template>
  <el-dialog v-model="visible" title="主题设置" width="760px" append-to-body align-center draggable>
    <div class="flex items-center justify-between mb-12px">
      <el-button type="primary" text @click="handleStartCreate" :disabled="isEditingAny"
        >+新增主题</el-button
      >
    </div>
    <div class="text-12px text-text-secondary mb-12px">支持行内新增和修改主题</div>

    <el-table :data="tableRows" border row-key="__sourceKey">
      <el-table-column prop="key" label="主题名称" min-width="220">
        <template #default="{ row }">
          <template v-if="isEditingRow(row)">
            <el-input
              v-model="editForm.key"
              spellcheck="false"
              clearable
              :disabled="row.__sourceKey === DEFAULT_THEME_KEY"
              placeholder="如 dark_theme"
              @input="sanitizeEditKey"
            />
          </template>
          <template v-else>
            <div class="flex items-center gap-6px">
              <span>{{ row.key }}</span>
              <el-tag v-if="row.key === DEFAULT_THEME_KEY" size="small" type="success">默认</el-tag>
            </div>
          </template>
        </template>
      </el-table-column>

      <el-table-column prop="description" label="描述">
        <template #default="{ row }">
          <el-input
            v-if="isEditingRow(row)"
            v-model="editForm.description"
            spellcheck="false"
            clearable
            placeholder="描述（可选）"
          />
          <span v-else>{{ row.description }}</span>
        </template>
      </el-table-column>

      <el-table-column label="显示主题" width="100" align="center">
        <template #default="{ row }">
          <el-radio v-model="displayTheme" :value="row.key" :disabled="row.__isNew" />
        </template>
      </el-table-column>

      <el-table-column label="操作" width="150" align="center">
        <template #default="{ row }">
          <template v-if="isEditingRow(row)">
            <el-button type="primary" text @click="handleSaveRow(row)">保存</el-button>
            <el-button text @click="handleCancelEdit(row)">取消</el-button>
          </template>
          <template v-else>
            <el-button
              v-if="row.key !== DEFAULT_THEME_KEY"
              type="primary"
              text
              @click="handleStartEdit(row)"
              >编辑</el-button
            >
            <el-button
              type="danger"
              text
              v-if="row.key !== DEFAULT_THEME_KEY"
              @click="handleDeleteTheme(row.key)"
            >
              删除
            </el-button>
          </template>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>

<script setup lang="ts">
import type { Theme } from '@/types/theme'

import { computed, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useI18n } from 'vue-i18n'
import { useProjectStore } from '@/store/modules/project'
import { DEFAULT_THEME_KEY } from '@/constants'

type TableThemeRow = Theme & {
  __isNew: boolean
  __sourceKey: string
}

const visible = ref(false)
const projectStore = useProjectStore()
const { t } = useI18n()
const THEME_NAME_REG = /^[A-Za-z_][A-Za-z0-9_]*$/

const creatingRow = ref(false)
const editingSourceKey = ref<string | null>(null)
const editForm = ref({
  key: '',
  description: ''
})

const themes = computed(() => {
  const project = projectStore.project
  if (!project) return [] as Theme[]
  return project.themes || []
})

const tableRows = computed<TableThemeRow[]>(() => {
  const rows = themes.value.map((item) => ({
    ...item,
    __isNew: false,
    __sourceKey: item.key
  }))

  if (creatingRow.value) {
    rows.push({
      key: '',
      default: false,
      description: '',
      __isNew: true,
      __sourceKey: '__new__'
    })
  }

  return rows
})

const isEditingAny = computed(() => !!editingSourceKey.value)

const displayTheme = computed({
  get() {
    return projectStore.project?.currentTheme || DEFAULT_THEME_KEY
  },
  set(val: string) {
    projectStore.setCurrentTheme(val)
  }
})

const ensureProject = () => {
  if (projectStore.project) return true

  ElMessage.warning(t('createProjectFirst'))
  return false
}

const sanitizeEditKey = () => {
  const normalized = editForm.value.key.replace(/[^A-Za-z0-9_]/g, '').replace(/^[^A-Za-z_]+/, '')
  if (normalized !== editForm.value.key) {
    editForm.value.key = normalized
  }
}

const isEditingRow = (row: TableThemeRow) => {
  return editingSourceKey.value === row.__sourceKey
}

const handleStartCreate = () => {
  if (!ensureProject()) return
  if (isEditingAny.value) return

  creatingRow.value = true
  editingSourceKey.value = '__new__'
  editForm.value.key = ''
  editForm.value.description = ''
}

const handleStartEdit = (row: TableThemeRow) => {
  if (!ensureProject()) return
  if (isEditingAny.value) return

  editingSourceKey.value = row.__sourceKey
  editForm.value.key = row.key
  editForm.value.description = row.description || ''
}

const validateThemeKey = (key: string, sourceKey?: string) => {
  if (!key) {
    ElMessage.warning('请输入主题名称')
    return false
  }

  if (!THEME_NAME_REG.test(key)) {
    ElMessage.warning('主题名称仅支持字母、数字、下划线，且需以字母或下划线开头')
    return false
  }

  const duplicated = themes.value.some((item) => item.key === key && item.key !== sourceKey)
  if (duplicated) {
    ElMessage.warning('主题名称不能重复')
    return false
  }

  return true
}

const resetEditState = () => {
  creatingRow.value = false
  editingSourceKey.value = null
  editForm.value.key = ''
  editForm.value.description = ''
}

const handleCancelEdit = (row: TableThemeRow) => {
  if (row.__isNew) {
    resetEditState()
    return
  }

  resetEditState()
}

const handleSaveRow = (row: TableThemeRow) => {
  if (!ensureProject()) return

  const key = editForm.value.key.trim()
  const description = editForm.value.description.trim()

  if (row.__sourceKey === DEFAULT_THEME_KEY && key !== DEFAULT_THEME_KEY) {
    ElMessage.warning(`${DEFAULT_THEME_KEY} 不允许修改主题名称`)
    return
  }

  if (!validateThemeKey(key, row.__isNew ? undefined : row.__sourceKey)) {
    return
  }

  if (row.__isNew) {
    projectStore.project!.themes.push({
      key,
      default: key === DEFAULT_THEME_KEY,
      description
    })
    projectStore.normalizeThemes()
    resetEditState()
    return
  }

  const target = themes.value.find((item) => item.key === row.__sourceKey)
  if (!target) {
    resetEditState()
    return
  }

  const oldKey = target.key
  target.key = key
  target.description = description
  target.default = key === DEFAULT_THEME_KEY

  if (oldKey !== key) {
    projectStore.renameThemeStyles(oldKey, key)
  }

  projectStore.normalizeThemes()
  resetEditState()
}

const handleDeleteTheme = (themeKey: string) => {
  if (!ensureProject()) return
  if (themeKey === DEFAULT_THEME_KEY) {
    ElMessage.warning(`${DEFAULT_THEME_KEY} 不允许删除`)
    return
  }

  ElMessageBox.confirm(t('deleteConfirm'), t('tip'), {
    confirmButtonText: t('confirm'),
    cancelButtonText: t('cancel'),
    type: 'warning'
  }).then(() => {
    const index = themes.value.findIndex((item) => item.key === themeKey)
    if (index !== -1) {
      themes.value.splice(index, 1)
      projectStore.removeThemeStyles(themeKey)
      projectStore.normalizeThemes()
      if (editingSourceKey.value === themeKey) {
        resetEditState()
      }
    }
  })
}

defineExpose({
  open() {
    if (!ensureProject()) return

    projectStore.normalizeThemes()
    resetEditState()
    visible.value = true
  }
})
</script>

<style scoped></style>
