<template>
  <div class="app-container">
    <!-- 搜索表单 -->
    <el-form
      :model="queryParams"
      ref="queryFormRef"
      size="small"
      :inline="true"
      v-show="showSearch"
      label-width="68px"
    >
      <el-form-item label="表名称" prop="tableName">
        <el-input
          v-model="queryParams.tableName"
          placeholder="请输入表名称"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="表描述" prop="tableComment">
        <el-input
          v-model="queryParams.tableComment"
          placeholder="请输入表描述"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker
          v-model="dateRange"
          style="width: 240px"
          value-format="YYYY-MM-DD"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          @change="handleDateChange"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :icon="Search" size="small" @click="handleQuery">
          搜索
        </el-button>
        <el-button :icon="Refresh" size="small" @click="resetQuery">
          重置
        </el-button>
      </el-form-item>
    </el-form>

    <!-- 操作按钮 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          :icon="Download"
          size="small"
          :disabled="multiple"
          @click="handleGenTable"
        >
          生成
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          :icon="Plus"
          size="small"
          @click="openCreateTable"
        >
          创建
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          :icon="Upload"
          size="small"
          @click="openImportTable"
        >
          导入
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          :icon="Edit"
          size="small"
          :disabled="single"
          @click="handleEditTable"
        >
          修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          :icon="Delete"
          size="small"
          :disabled="multiple"
          @click="handleDelete"
        >
          删除
        </el-button>
      </el-col>
<!--      <RightToolbar :show-search="showSearch" @query-table="getList" />-->
    </el-row>

    <!-- 数据表格 -->
    <el-table
      v-loading="loading"
      :data="tableList"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <el-table-column type="selection" align="center" width="55" />
      <el-table-column label="序号" width="50" align="center">
        <template #default="{ $index }">
          <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + $index + 1 }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="表名称"
        align="center"
        prop="tableName"
        :show-overflow-tooltip="true"
        width="260"
        sortable="custom"
      />
      <el-table-column
        label="表描述"
        align="center"
        prop="tableComment"
        :show-overflow-tooltip="true"
        width="220"
        sortable="custom"
      />
      <el-table-column
        label="实体"
        align="center"
        prop="className"
        :show-overflow-tooltip="true"
        width="220"
      />
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="160"
        sortable="custom"
      />
      <el-table-column
        label="更新时间"
        align="center"
        prop="updateTime"
        width="160"
        sortable="custom"
      />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="{ row }">
          <el-button
            type="text"
            size="small"
            :icon="View"
            @click="handlePreview(row)"
            v-has-permi="['tool:gen:preview']"
          >
            预览
          </el-button>
          <el-button
            type="text"
            size="small"
            :icon="Edit"
            @click="handleEditTable(row)"
            v-has-permi="['tool:gen:edit']"
          >
            编辑
          </el-button>
          <el-button
            type="text"
            size="small"
            :icon="Delete"
            @click="handleDelete(row)"
            v-has-permi="['tool:gen:remove']"
          >
            删除
          </el-button>
          <el-button
            type="text"
            size="small"
            :icon="Refresh"
            @click="handleSynchDb(row)"
            v-has-permi="['tool:gen:edit']"
          >
            同步
          </el-button>
          <el-button
            type="text"
            size="small"
            :icon="Download"
            @click="handleGenTable(row)"
          >
            生成代码
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <Pagination
      v-show="total > 0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 代码预览对话框 -->
    <el-dialog
      :title="preview.title"
      v-model="preview.open"
      width="80%"
      top="5vh"
      append-to-body
      class="scrollbar"
      @close="handlePreviewClose"
    >
      <el-tabs v-model="preview.activeName" type="border-card">
        <el-tab-pane
          v-for="(value, key) in preview.data"
          :label="getTabLabel(key)"
          :name="getTabName(key)"
          :key="key"
        >
          <template #label>
            <span class="tab-label">{{ getTabLabel(key) }}</span>
          </template>
          <div class="code-header">
            <el-tooltip content="复制代码" placement="top">
              <el-button
                :icon="DocumentCopy"
                @click="handleCopy(value)"
                size="small"
                text
              >
                复制
              </el-button>
            </el-tooltip>
          </div>
          <div class="code-container">
            <pre><code class="hljs" v-html="highlightedCode(value, key)"></code></pre>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>

    <!-- 子组件 -->
    <ImportTable ref="importRef" @ok="handleQuery" />
    <CreateTable ref="createRef" @ok="handleQuery" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import type { FormInstance, TableColumnCtx } from 'element-plus'
import {
  Search,
  Refresh,
  Download,
  Plus,
  Upload,
  Edit,
  Delete,
  View,
  DocumentCopy
} from '@element-plus/icons-vue'

// API
import {
  listTable,
  previewTable,
  delTable,
  genCode,
  synchDb,
  type GenTableInfo,
  type GenTableQuery, batchGenCode
} from '@/apis/gen/gen'

// 组件
import ImportTable from './importTable.vue'
import CreateTable from './createTable.vue'
// import RightToolbar from '@/components/RightToolbar/NewDeclaredGodds.vue'
import Pagination from '@/components/Pagination/index.vue'

// Highlight.js 配置
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import xml from 'highlight.js/lib/languages/xml'
import json from 'highlight.js/lib/languages/json'
import sql from 'highlight.js/lib/languages/sql'
import java from 'highlight.js/lib/languages/java'
import css from 'highlight.js/lib/languages/css'

// 注册语言
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('xml', xml)
hljs.registerLanguage('json', json)
hljs.registerLanguage('sql', sql)
hljs.registerLanguage('java', java)
hljs.registerLanguage('css', css)

// 类型定义
interface PreviewData {
  open: boolean
  title: string
  data: Record<string, string>
  activeName: string
}

interface SortParams {
  prop: string
  order: 'ascending' | 'descending'
}

// 路由
const route = useRoute()
const router = useRouter()

// Refs
const queryFormRef = ref<FormInstance>()
const importRef = ref<InstanceType<typeof ImportTable>>()
const createRef = ref<InstanceType<typeof CreateTable>>()

// 响应式数据
const loading = ref(true)
const uniqueId = ref('')
const selectedRows = ref<GenTableInfo[]>([])
const showSearch = ref(true)
const total = ref(0)
const tableList = ref<GenTableInfo[]>([])
const dateRange = ref<string[]>([])

const queryParams = reactive<GenTableQuery & { sort?: string; order?: string }>({
  pageNum: 1,
  pageSize: 10,
  tableName: undefined,
  tableComment: undefined
})

const preview = reactive<PreviewData>({
  open: false,
  title: '代码预览',
  data: {},
  activeName: 'domain.java'
})

// 计算属性
const ids = computed(() => selectedRows.value.map(item => item.tableId))
const tableNames = computed(() => selectedRows.value.map(item => item.tableName))
const single = computed(() => selectedRows.value.length !== 1)
const multiple = computed(() => selectedRows.value.length === 0)

// 生命周期
onMounted(() => {
  getList()
})



// 方法
/** 查询表集合 */
const getList = async () => {
  try {
    loading.value = true

    // 构建请求参数
    const params: GenTableQuery = { ...queryParams }
    if (dateRange.value && dateRange.value.length === 2) {
      params.beginTime = dateRange.value[0]
      params.endTime = dateRange.value[1]
    }

    const response = await listTable(params)
    console.log(response);
    if (response.code === 200) {
      tableList.value = response.rows
      total.value = response.total
    } else {
      ElMessage.error(response.msg || '获取数据失败')
    }
  } catch (error) {
    ElMessage.error('网络错误，请稍后重试')
    console.error('获取表列表失败:', error)
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNum = 1
  getList()
}

/** 日期范围变化 */
const handleDateChange = (value: string[]) => {
  dateRange.value = value
}

/** 生成代码操作 */
/** 生成代码操作 */
const handleGenTable = async (row?: GenTableInfo) => {
  const targetTableNames = row?.tableName || tableNames.value.join(',')

  if (!targetTableNames) {
    ElMessage.error('请选择要生成的数据')
    return
  }

  try {
    loading.value = true
    console.log('开始生成代码，表名：', targetTableNames)

    // 使用 axios 下载
    const response = await batchGenCode(targetTableNames)
    console.log('完整响应对象:', response)
    console.log('响应状态:', response.status)
    console.log('响应头:', response.headers)
    console.log('响应数据类型:', typeof response.data)
    console.log('响应数据构造函数:', response.data?.constructor?.name)
    console.log('响应数据:', response.data)

    // 检查是否是 Blob
    if (response.data instanceof Blob) {
      console.log('是 Blob 对象，大小:', response.data.size, '类型:', response.data.type)
    } else {
      console.log('不是 Blob 对象，实际类型:', typeof response.data)
      // 尝试查看内容
      try {
        const text = await new Response(response.data).text()
        console.log('响应内容:', text.substring(0, 200)) // 只显示前200个字符
      } catch (e) {
        console.log('无法读取响应内容')
      }
    }

    // 只有确认是 Blob 才创建 URL
    if (response.data instanceof Blob && response.data.size > 0) {
      const url = window.URL.createObjectURL(response.data)
      const link = document.createElement('a')
      link.href = url
      link.download = targetTableNames.includes(',') ? 'codes.zip' : `${targetTableNames}.zip`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
      ElMessage.success('代码生成成功')
    } else {
      throw new Error('响应不是有效的文件数据')
    }

  } catch (error: any) {
    console.error('生成代码失败:', error)
    ElMessage.error('生成代码失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

/** 同步数据库操作 */
const handleSynchDb = async (row: GenTableInfo) => {
  try {
    await ElMessageBox.confirm(
      `确认要强制同步"${row.tableName}"表结构吗？`,
      '系统提示',
      {
        type: 'warning',
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }
    )

    const response = await synchDb(row.tableName)
    if (response.code === 200) {
      ElMessage.success('同步成功')
      getList() // 刷新列表
    } else {
      ElMessage.error(response.msg || '同步失败')
    }
  } catch (error) {
    // 用户取消操作
  }
}

/** 打开导入表弹窗 */
const openImportTable = () => {
  importRef.value?.show()
}

/** 打开创建表弹窗 */
const openCreateTable = () => {
  createRef.value?.show()
}

/** 重置按钮操作 */
const resetQuery = () => {
  dateRange.value = []
  if (queryFormRef.value) {
    queryFormRef.value.resetFields()
  }
  queryParams.sort = undefined
  queryParams.order = undefined
  handleQuery()
}

/** 预览按钮 */
const handlePreview = async (row: GenTableInfo) => {
  try {
    const response = await previewTable(row.tableId)
    if (response.code === 200) {
      preview.data = response.data
      preview.open = true
      preview.activeName = Object.keys(response.data)[0]?.split('/').pop()?.split('.vm')[0] || 'domain.java'
    } else {
      ElMessage.error(response.msg || '预览失败')
    }
  } catch (error) {
    ElMessage.error('预览失败')
    console.error('预览失败:', error)
  }
}

/** 关闭预览 */
const handlePreviewClose = () => {
  preview.data = {}
  preview.activeName = 'domain.java'
}

/** 获取标签页名称 */
const getTabName = (key: string) => {
  const lastSlashIndex = key.lastIndexOf('/')
  const vmIndex = key.indexOf('.vm')
  return key.substring(lastSlashIndex + 1, vmIndex)
}

/** 获取标签页显示标签 */
const getTabLabel = (key: string) => {
  return getTabName(key)
}

/** 高亮显示代码 */
const highlightedCode = (code: string, key: string) => {
  const vmName = getTabName(key)
  const language = vmName.substring(vmName.lastIndexOf('.') + 1)

  try {
    const result = hljs.highlight(code || '', {
      language: getLanguageAlias(language)
    })
    return result.value || '&nbsp;'
  } catch (error) {
    return code || '&nbsp;'
  }
}

/** 获取语言别名 */
const getLanguageAlias = (language: string): string => {
  const aliases: Record<string, string> = {
    'java': 'java',
    'xml': 'xml',
    'html': 'xml',
    'js': 'javascript',
    'javascript': 'javascript',
    'json': 'json',
    'sql': 'sql',
    'css': 'css',
    'vue': 'xml'
  }
  return aliases[language] || 'plaintext'
}

/** 复制代码 */
const handleCopy = async (code: string) => {
  try {
    await navigator.clipboard.writeText(code)
    ElMessage.success('复制成功')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

/** 多选框选中数据 */
const handleSelectionChange = (selection: GenTableInfo[]) => {
  selectedRows.value = selection
}

/** 表格排序 */
const handleSortChange = ({ prop, order }: SortParams) => {
  if (prop && order) {
    queryParams.sort = prop
    queryParams.order = order === 'ascending' ? 'asc' : 'desc'
  } else {
    queryParams.sort = undefined
    queryParams.order = undefined
  }
  getList()
}

/** 修改按钮操作 */
const handleEditTable = (row?: GenTableInfo) => {
  const tableId = row?.tableId || ids.value[0]
  const tableName = row?.tableName || tableNames.value[0]

  // 使用 name 跳转而不是 path
  router.push({
    name: 'GenEdit', // 使用路由名称
    params: { tableId },
    query: {
      pageNum: queryParams.pageNum.toString(),
      tableName
    }
  })
  /*// 路由跳转到编辑页面
  router.push({
    path: `/gen/gen-edit/${tableId}`,
    query: {
      pageNum: queryParams.pageNum.toString(),
      tableName
    }
  })*/
}

/** 删除按钮操作 */
const handleDelete = async (row?: GenTableInfo) => {
  const tableIds = row?.tableId || ids.value

  try {
    await ElMessageBox.confirm(
      `是否确认删除表编号为"${Array.isArray(tableIds) ? tableIds.join(',') : tableIds}"的数据项？`,
      '系统提示',
      {
        type: 'warning',
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }
    )

    const response = await delTable(tableIds)
    if (response.code === 200) {
      ElMessage.success('删除成功')
      getList()
    } else {
      ElMessage.error(response.msg || '删除失败')
    }
  } catch (error) {
    // 用户取消操作
  }
}

// 监听路由变化
import { watch } from 'vue'
watch(
  () => route.query,
  (newQuery) => {
    const time = newQuery.t as string
    if (time && time !== uniqueId.value) {
      uniqueId.value = time
      queryParams.pageNum = Number(newQuery.pageNum) || 1
      getList()
    }
  },
  { immediate: true }
)
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.mb8 {
  margin-bottom: 8px;
}

.scrollbar {
  max-height: 70vh;
  overflow-y: auto;
}

.code-header {
  display: flex;
  justify-content: flex-end;
  padding: 8px 0;
  border-bottom: 1px solid #e8e8e8;
  margin-bottom: 12px;
}

.code-container {
  background: #f8f9fa;
  border-radius: 4px;
  padding: 16px;
  overflow-x: auto;
}

.hljs {
  background: transparent !important;
  padding: 0 !important;
  font-family: 'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
}

.tab-label {
  font-weight: 500;
}

:deep(.el-table .small-padding) {
  padding: 8px 0;
}

:deep(.el-tabs__content) {
  position: relative;
}

:deep(.el-tabs--border-card > .el-tabs__content) {
  padding: 16px;
}
</style>
