import { ref, computed, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import type { Database, TableInfo, ColumnInfo, DbForm } from './types'

// API 基础 URL
const API_BASE = 'http://localhost:8082'

// 解析 DDL 获取列信息
function parseDDLColumns(ddl: string): ColumnInfo[] {
  const columns: ColumnInfo[] = []
  if (!ddl) return columns

  // 移除 CREATE TABLE 语句，只保留括号内的内容
  const match = ddl.match(/\(([\s\S]*)\)\s*.*$/m)
  if (!match) return columns

  const body = match[1]

  // 按换行或逗号分割列定义（处理多行的情况）
  const lines = body.split(/,\s*(?=`\w+`|\s*$)/)

  for (const line of lines) {
    const trimmed = line.trim()
    if (!trimmed || trimmed.startsWith('PRIMARY KEY') || trimmed.startsWith('KEY ') ||
        trimmed.startsWith('UNIQUE KEY') || trimmed.startsWith('FULLTEXT') ||
        trimmed.startsWith('CONSTRAINT') || trimmed.startsWith('FOREIGN KEY') ||
        trimmed.startsWith('ENGINE') || trimmed.startsWith('CHARSET') || trimmed.startsWith(')')) {
      continue
    }

    // 解析列名（支持反引号和单引号）
    const colNameMatch = trimmed.match(/^`?(\w+)`?\s+/)
    if (!colNameMatch) continue

    const name = colNameMatch[1]

    // 提取列定义剩余部分
    const rest = trimmed.substring(colNameMatch[0].length)

    // 提取数据类型（到 NOT NULL / DEFAULT / COMMENT 之前）
    const typeMatch = rest.match(/^([^\s]+(?:\s*\([^\)]+\))?)/)
    const type = typeMatch ? typeMatch[1] : ''

    // 提取 COMMENT
    const commentMatch = trimmed.match(/COMMENT\s+['"]([^'"]*)['"]/i)
    const comment = commentMatch ? commentMatch[1] : ''

    // 提取默认值
    const defaultMatch = trimmed.match(/DEFAULT\s+([^\s,]+)/i)
    const defaultValue = defaultMatch ? defaultMatch[1] : ''

    // 判断是否可空
    const isNullable = trimmed.includes('NOT NULL') ? 'NO' : 'YES'

    // 判断是否是主键
    const isPrimaryKey = trimmed.includes('PRIMARY KEY')

    columns.push({
      name,
      type,
      comment,
      mapped_name: '',
      column_type: type,
      is_nullable: isNullable,
      default_value: defaultValue,
      column_key: isPrimaryKey ? 'PRI' : '',
    })
  }

  return columns
}

export function useDatabase() {
  // 数据库数据
  const databases = ref<Database[]>([])
  const loading = ref(false)

  // 编辑状态
  const editingDb = ref<Database | null>(null)
  const isEditing = ref(false)
  const isCreating = ref(false)
  const searchQuery = ref('')

  // 表映射弹窗状态
  const isMapping = ref(false)
  const mappingDb = ref<Database | null>(null)
  const tables = ref<TableInfo[]>([])
  const tableLoading = ref(false)
  const tableSearchQuery = ref('')
  const selectedTables = ref<TableInfo[]>([])
  const tablePage = ref(1)
  const tablePageSize = ref(10)
  const currentTableIndex = ref(0)

  // 映射步骤：1-选择表, 2-DDl和映射
  const mappingStep = ref(1)

  // 新建表单
  const newDbForm = ref<DbForm>({
    name: '',
    db_type: 'MySQL',
    description: '',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: '',
    database: '',
  })

  // 编辑表单
  const editForm = ref<DbForm>({
    name: '',
    db_type: '',
    description: '',
    host: '',
    port: 0,
    username: '',
    password: '',
    database: '',
  })

  const dbTypes = ['MySQL', 'Neo4j']

  // 监听数据库类型变化，自动设置默认端口
  watch(() => newDbForm.value.db_type, (newType) => {
    if (newType === 'Neo4j') {
      newDbForm.value.port = 7687
      newDbForm.value.username = 'neo4j'
    } else if (newType === 'MySQL') {
      newDbForm.value.port = 3306
      newDbForm.value.username = 'root'
    }
  })

  // 搜索时重置分页
  watch(tableSearchQuery, () => {
    tablePage.value = 1
  })

  // 当前正在编辑的表
  const selectedTable = computed(() => {
    if (selectedTables.value.length === 0) return null
    return selectedTables.value[currentTableIndex.value] || null
  })

  // 过滤后的表
  const filteredTables = () => {
    let result = tables.value
    if (tableSearchQuery.value) {
      result = result.filter(t => t.name.toLowerCase().includes(tableSearchQuery.value.toLowerCase()))
    }
    return result
  }

  const paginatedTables = computed(() => {
    const start = (tablePage.value - 1) * tablePageSize.value
    const end = start + tablePageSize.value
    return filteredTables().slice(start, end)
  })

  const totalFilteredTables = computed(() => filteredTables().length)

  // 过滤后的 Databases
  const filteredDatabases = () => {
    return databases.value.filter(db => {
      const matchSearch = !searchQuery.value ||
        db.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
        db.db_type.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
        db.host.toLowerCase().includes(searchQuery.value.toLowerCase())
      return matchSearch
    })
  }

  // 检查表是否被选中
  const isTableSelected = (tableName: string) => {
    return selectedTables.value.some(t => t.name === tableName)
  }

  // 切换表的选择状态
  const toggleTableSelection = (table: TableInfo) => {
    const index = selectedTables.value.findIndex(t => t.name === table.name)
    if (index >= 0) {
      selectedTables.value.splice(index, 1)
      if (currentTableIndex.value >= selectedTables.value.length) {
        currentTableIndex.value = Math.max(0, selectedTables.value.length - 1)
      }
    } else {
      selectedTables.value.push(table)
    }
  }

  // 全选所有表
  const selectAllTables = () => {
    selectedTables.value = [...filteredTables()]
    currentTableIndex.value = 0
  }

  // 清除所有选择
  const clearAllTables = () => {
    selectedTables.value = []
    currentTableIndex.value = 0
  }

  // 上一张表
  const prevTable = () => {
    if (currentTableIndex.value > 0) {
      currentTableIndex.value--
    }
  }

  // 下一张表
  const nextTable = () => {
    if (currentTableIndex.value < selectedTables.value.length - 1) {
      currentTableIndex.value++
    }
  }

  // 获取列表数据
  const fetchDatabases = async () => {
    loading.value = true
    try {
      const response = await fetch(`${API_BASE}/database/list`)
      if (!response.ok) {
        throw new Error('Failed to fetch databases')
      }
      const data = await response.json()
      databases.value = data.list || []
    } catch (error) {
      console.error('Failed to fetch databases:', error)
      ElMessage.error('Failed to load databases')
      databases.value = []
    } finally {
      loading.value = false
    }
  }

  // 打开新建弹窗
  const openCreate = () => {
    newDbForm.value = {
      name: '',
      db_type: 'MySQL',
      description: '',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: '',
      database: '',
    }
    isCreating.value = true
  }

  // 关闭新建弹窗
  const closeCreate = () => {
    isCreating.value = false
  }

  // 关闭映射弹窗
  const closeMapping = () => {
    isMapping.value = false
    mappingDb.value = null
    tables.value = []
    selectedTables.value = []
    currentTableIndex.value = 0
    mappingStep.value = 1
    tableSearchQuery.value = ''
    tablePage.value = 1
  }

  // 测试连接并获取表列表
  const testConnect = async () => {
    try {
      const response = await fetch(`${API_BASE}/database/check`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          db_type: newDbForm.value.db_type,
          host: newDbForm.value.host,
          port: newDbForm.value.port,
          username: newDbForm.value.username,
          password: newDbForm.value.password,
          database: newDbForm.value.database,
          charset: 'utf8mb4',
        }),
      })

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`)
      }

      const result = await response.json()

      if (result.success) {
        const dbInfo: Database = {
          id: '',
          name: newDbForm.value.name || 'Untitled Database',
          description: newDbForm.value.description,
          db_type: newDbForm.value.db_type,
          host: newDbForm.value.host,
          port: newDbForm.value.port,
          username: newDbForm.value.username,
          password: newDbForm.value.password,
          database: newDbForm.value.database,
          table_count: 0,
          created_at: '',
          updated_at: '',
        }

        if (result.tables && result.tables.length > 0) {
          tables.value = result.tables.map((table: any) => {
            const ddl = table.ddl || ''
            let columns: ColumnInfo[]
            if (table.columns && table.columns.length > 0) {
              columns = table.columns.map((col: any) => ({
                name: col.column_name,
                type: col.data_type || col.column_type || '',
                column_type: col.column_type || '',
                comment: col.column_comment || '',
                is_nullable: col.is_nullable || '',
                default_value: col.default_value || '',
                column_key: col.column_key || '',
                mapped_name: '',
              }))
            } else if (ddl) {
              columns = parseDDLColumns(ddl)
            } else {
              columns = []
            }

            return {
              name: table.table_name,
              table_comment: table.table_comment || '',
              ddl,
              columns,
            }
          })
        }

        selectedTables.value = []
        currentTableIndex.value = 0
        mappingStep.value = 1
        mappingDb.value = dbInfo
        isMapping.value = true
        isCreating.value = false
        ElMessage.success('Connection successful! Please select tables to map.')
      } else {
        ElMessage.error(result.message || 'Connection failed')
      }
    } catch (error: any) {
      console.error('Connection test failed:', error)
      ElMessage.error('Connection test failed: ' + error.message)
    }
  }

  // 打开映射弹窗
  const openMapping = async (db: Database) => {
    mappingDb.value = db
    tables.value = []
    selectedTables.value = []
    currentTableIndex.value = 0
    mappingStep.value = 1
    tableLoading.value = true
    isMapping.value = true

    try {
      const [checkRes, mappingRes] = await Promise.all([
        fetch(`${API_BASE}/database/check`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            db_type: db.db_type,
            host: db.host,
            port: db.port,
            username: db.username,
            password: db.password,
            database: db.database,
            charset: 'utf8mb4',
          }),
        }),
        db.id ? fetch(`${API_BASE}/sub-table/database/${db.id}`) : Promise.resolve(null),
      ])

      if (!checkRes.ok) {
        throw new Error(`HTTP ${checkRes.status}`)
      }

      const result = await checkRes.json()

      let savedMappings: any = {}
      let savedTableNames: string[] = []
      if (mappingRes && mappingRes.ok) {
        const mappingResult = await mappingRes.json()
        const tablesList = mappingResult.list || mappingResult.tables || []
        for (const table of tablesList) {
          savedMappings[table.parent_table] = table.fields || []
          savedTableNames.push(table.parent_table)
        }
      }

      if (result.success && result.tables) {
        tables.value = result.tables.map((table: any) => {
          const ddl = table.ddl || ''
          const savedFields = savedMappings[table.table_name] || []

          let columns: ColumnInfo[]
          if (table.columns && table.columns.length > 0) {
            columns = table.columns.map((col: any) => {
              const savedField = savedFields.find((f: any) => f.column_name === col.column_name)
              return {
                name: col.column_name,
                type: col.data_type || col.column_type || '',
                column_type: col.column_type || '',
                comment: col.column_comment || '',
                is_nullable: col.is_nullable || '',
                default_value: col.default_value || '',
                column_key: col.column_key || '',
                mapped_name: savedField?.mapped_name || col.mapped_name || '',
              }
            })
          } else if (ddl) {
            columns = parseDDLColumns(ddl).map(col => {
              const savedField = savedFields.find((f: any) => f.column_name === col.name)
              return {
                ...col,
                mapped_name: savedField?.mapped_name || '',
              }
            })
          } else {
            columns = []
          }

          return {
            name: table.table_name,
            table_comment: table.table_comment || '',
            ddl,
            columns,
          }
        })

        if (savedTableNames.length > 0) {
          selectedTables.value = tables.value.filter(t => savedTableNames.includes(t.name))
        } else {
          selectedTables.value = []
        }
        currentTableIndex.value = 0
      } else {
        ElMessage.warning(result.message || '获取表结构失败')
      }
    } catch (error: any) {
      console.error('获取表结构失败:', error)
      ElMessage.error('获取表结构失败: ' + error.message)
    } finally {
      tableLoading.value = false
    }
  }

  // 进入下一步
  const goToStep2 = () => {
    if (selectedTables.value.length > 0) {
      mappingStep.value = 2
      currentTableIndex.value = 0
    }
  }

  // 返回上一步
  const goToStep1 = () => {
    mappingStep.value = 1
  }

  // 保存映射
  const saveMapping = async () => {
    if (!mappingDb.value) {
      ElMessage.warning('数据库信息不存在')
      return
    }

    const isEditing = !!mappingDb.value.id
    const subTablesData = selectedTables.value.map(table => ({
      parent_table: table.name,
      sub_table_name: table.table_comment || table.name,
      sub_table_comment: table.table_comment || '',
      ddl: table.ddl || '',
    }))

    try {
      let response: Response

      if (isEditing) {
        response = await fetch(`${API_BASE}/database/${mappingDb.value.id}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: mappingDb.value.name,
            description: mappingDb.value.description,
            db_type: mappingDb.value.db_type,
            host: mappingDb.value.host,
            port: mappingDb.value.port,
            username: mappingDb.value.username,
            password: mappingDb.value.password,
            database: mappingDb.value.database,
            sub_tables: subTablesData,
          }),
        })
      } else {
        response = await fetch(`${API_BASE}/database/add`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: mappingDb.value.name,
            description: mappingDb.value.description,
            db_type: mappingDb.value.db_type,
            host: mappingDb.value.host,
            port: mappingDb.value.port,
            username: mappingDb.value.username,
            password: mappingDb.value.password,
            database: mappingDb.value.database,
            sub_tables: subTablesData,
          }),
        })
      }

      if (response.ok) {
        const result = await response.json()
        if (!isEditing) {
          databases.value.push(result)
        }
        closeMapping()
        ElMessage.success(isEditing ? 'Mapping updated successfully' : 'Database created successfully')
        fetchDatabases()
      } else {
        const errorData = await response.json()
        ElMessage.error(errorData.error || (isEditing ? 'Failed to update mapping' : 'Failed to create database'))
      }
    } catch (error: any) {
      console.error('保存失败:', error)
      ElMessage.error('保存失败: ' + error.message)
    }
  }

  // 打开编辑弹窗
  const openEdit = (db: Database) => {
    editingDb.value = db
    editForm.value = {
      name: db.name,
      db_type: db.db_type,
      description: db.description,
      host: db.host,
      port: db.port,
      username: db.username,
      password: db.password,
      database: db.database,
    }
    isEditing.value = true
  }

  // 保存编辑
  const saveEdit = async () => {
    if (editingDb.value) {
      try {
        const response = await fetch(`${API_BASE}/database/${editingDb.value.id}`, {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: editForm.value.name,
            description: editForm.value.description,
            db_type: editForm.value.db_type,
            host: editForm.value.host,
            port: editForm.value.port,
            username: editForm.value.username,
            password: editForm.value.password,
            database: editForm.value.database,
          }),
        })
        if (response.ok) {
          const updatedDb = await response.json()
          const index = databases.value.findIndex(d => d.id === editingDb.value!.id)
          if (index !== -1) {
            databases.value[index] = updatedDb
          }
          ElMessage.success('Database updated successfully')
        } else {
          const errorData = await response.json()
          ElMessage.error(errorData.error || 'Failed to update database')
        }
      } catch (error) {
        console.error('Failed to update database:', error)
        ElMessage.error('Failed to update database')
      }
    }
    isEditing.value = false
  }

  // 取消编辑
  const cancelEdit = () => {
    isEditing.value = false
    editingDb.value = null
  }

  // 删除 Database
  const deleteDb = async (id: string) => {
    try {
      const response = await fetch(`${API_BASE}/database/${id}`, {
        method: 'DELETE'
      })
      if (response.ok) {
        databases.value = databases.value.filter(d => d.id !== id)
        ElMessage.success('Database deleted successfully')
      } else {
        ElMessage.error('Failed to delete database')
      }
    } catch (error) {
      console.error('Failed to delete database:', error)
      ElMessage.error('Failed to delete database')
    }
  }

  // 初始化
  onMounted(() => {
    fetchDatabases()
  })

  return {
    // State
    databases,
    loading,
    editingDb,
    isEditing,
    isCreating,
    searchQuery,
    isMapping,
    mappingDb,
    tables,
    tableLoading,
    tableSearchQuery,
    selectedTables,
    tablePage,
    tablePageSize,
    currentTableIndex,
    mappingStep,
    newDbForm,
    editForm,
    dbTypes,

    // Computed
    selectedTable,
    filteredDatabases,
    paginatedTables,
    totalFilteredTables,

    // Methods
    isTableSelected,
    toggleTableSelection,
    selectAllTables,
    clearAllTables,
    prevTable,
    nextTable,
    fetchDatabases,
    openCreate,
    closeCreate,
    closeMapping,
    testConnect,
    openMapping,
    goToStep2,
    goToStep1,
    saveMapping,
    openEdit,
    saveEdit,
    cancelEdit,
    deleteDb,
  }
}
