import type { ToolConfig } from './index'
import { apiFetch } from '@/lib/tauri'

// Uses relative URLs - works with Vite proxy in dev and Traefik in production
const API_BASE = ''

export function createDatabaseHandlers(): ToolConfig[] {
  return [
    {
      name: 'list_tables',
      description: 'Lista todas las tablas de la base de datos',
      category: 'database',
      schema: { type: 'object', properties: {} },
      handler: async () => {
        try {
          const res = await apiFetch(`${API_BASE}/api/database/tables`)
          if (!res.ok) throw new Error('Failed to fetch tables')
          const tables = await res.json()

          if (tables.length === 0) return 'No hay tablas'

          const tableList = tables.map((t: any) => `  - ${t.name}: ${t.count} registros`).join('\n')
          const total = tables.reduce((sum: number, t: any) => sum + t.count, 0)

          return `Tablas (${tables.length}):\n\n${tableList}\n\nTotal: ${total} registros`
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'get_table_schema',
      description: 'Obtiene el esquema de una tabla',
      category: 'database',
      schema: {
        type: 'object',
        properties: {
          table: { type: 'string', description: 'Nombre de la tabla' }
        },
        required: ['table']
      },
      handler: async (args: { table: string }) => {
        try {
          const res = await apiFetch(`${API_BASE}/api/database/tables/${args.table}/schema`)
          if (!res.ok) {
            if (res.status === 404) return `Tabla "${args.table}" no encontrada`
            throw new Error('Failed to fetch schema')
          }
          const schema = await res.json()

          if (schema.length === 0) return `La tabla "${args.table}" no tiene columnas`

          const columns = schema.map((col: any) => {
            const flags = []
            if (col.pk) flags.push('PK')
            if (col.notnull) flags.push('NOT NULL')
            const flagStr = flags.length > 0 ? ` (${flags.join(', ')})` : ''
            return `  - ${col.name}: ${col.type}${flagStr}`
          }).join('\n')

          return `Esquema de "${args.table}":\n\n${columns}`
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'get_table_data',
      description: 'Obtiene datos de una tabla',
      category: 'database',
      schema: {
        type: 'object',
        properties: {
          table: { type: 'string', description: 'Nombre de la tabla' },
          limit: { type: 'number', description: 'Limite de registros (max 100)' },
          offset: { type: 'number', description: 'Offset para paginacion' }
        },
        required: ['table']
      },
      handler: async (args: { table: string; limit?: number; offset?: number }) => {
        try {
          const limit = Math.min(args.limit || 20, 100)
          const offset = args.offset || 0

          const res = await apiFetch(
            `${API_BASE}/api/database/tables/${args.table}/data?limit=${limit}&offset=${offset}`
          )
          if (!res.ok) {
            if (res.status === 404) return `Tabla "${args.table}" no encontrada`
            throw new Error('Failed to fetch data')
          }
          const result = await res.json()

          if (result.rows.length === 0) return `La tabla "${args.table}" no tiene registros`

          const rows = result.rows.map((row: any, idx: number) => {
            const entries = Object.entries(row).map(([k, v]) => {
              let value = v
              if (typeof v === 'string' && v.length > 50) {
                value = v.substring(0, 50) + '...'
              } else if (typeof v === 'object') {
                value = JSON.stringify(v).substring(0, 50) + '...'
              }
              return `${k}: ${value}`
            }).join(', ')
            return `[${offset + idx + 1}] ${entries}`
          }).join('\n')

          return `Datos de "${args.table}" (${offset + 1}-${offset + result.rows.length} de ${result.total}):\n\n${rows}`
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'get_database_stats',
      description: 'Obtiene estadisticas de la base de datos',
      category: 'database',
      schema: { type: 'object', properties: {} },
      handler: async () => {
        try {
          const res = await apiFetch(`${API_BASE}/api/database/stats`)
          if (!res.ok) throw new Error('Failed to fetch stats')
          const stats = await res.json()

          return `Estadisticas:\n\n` +
            `  Tamano: ${stats.size}\n` +
            `  Tablas: ${stats.tables}\n` +
            `  Registros: ${stats.totalRecords}\n\n` +
            `Desglose:\n` +
            stats.breakdown.map((t: any) => `  - ${t.name}: ${t.count}`).join('\n')
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'execute_query',
      description: 'Ejecuta una consulta SQL SELECT',
      category: 'database',
      schema: {
        type: 'object',
        properties: {
          query: { type: 'string', description: 'Consulta SQL (solo SELECT)' }
        },
        required: ['query']
      },
      handler: async (args: { query: string }) => {
        try {
          const res = await apiFetch(`${API_BASE}/api/database/query`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ query: args.query })
          })

          const result = await res.json()

          if (!res.ok) {
            return `Error: ${result.error}`
          }

          if (result.rows.length === 0) return 'Sin resultados'

          const columns = Object.keys(result.rows[0])
          const header = columns.join(' | ')
          const separator = columns.map(() => '---').join(' | ')
          const rows = result.rows.slice(0, 50).map((row: any) => {
            return columns.map(col => {
              let value = row[col]
              if (value === null) return 'NULL'
              if (typeof value === 'object') return JSON.stringify(value)
              if (typeof value === 'string' && value.length > 40) {
                return value.substring(0, 40) + '...'
              }
              return String(value)
            }).join(' | ')
          }).join('\n')

          const truncated = result.rows.length > 50 ? `\n\n... y ${result.rows.length - 50} filas mas` : ''

          return `Resultados (${result.rows.length}):\n\n${header}\n${separator}\n${rows}${truncated}`
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    }
  ]
}
