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

const API_BASE = ''

export function createGitHandlers(): ToolConfig[] {
  return [
    {
      name: 'get_git_status',
      description: 'Obtiene el estado actual del repositorio Git (archivos staged, unstaged, untracked)',
      category: 'git' as any,
      schema: {
        type: 'object',
        properties: {}
      },
      handler: async () => {
        try {
          const res = await apiFetch(`${API_BASE}/api/git/status`)
          if (!res.ok) {
            const err = await res.json()
            return `Error: ${err.error}`
          }

          const status = await res.json()
          let result = `Rama: ${status.branch}\n`

          if (status.ahead > 0 || status.behind > 0) {
            result += `Estado: `
            if (status.ahead > 0) result += `↑${status.ahead} ahead `
            if (status.behind > 0) result += `↓${status.behind} behind`
            result += '\n'
          }

          result += '\n'

          if (status.staged.length > 0) {
            result += `Staged (${status.staged.length}):\n`
            result += status.staged.map((f: any) => `  [${f.status.toUpperCase()[0]}] ${f.path}`).join('\n')
            result += '\n\n'
          }

          if (status.unstaged.length > 0) {
            result += `Unstaged (${status.unstaged.length}):\n`
            result += status.unstaged.map((f: any) => `  [${f.status.toUpperCase()[0]}] ${f.path}`).join('\n')
            result += '\n\n'
          }

          if (status.untracked.length > 0) {
            result += `Untracked (${status.untracked.length}):\n`
            result += status.untracked.map((f: string) => `  [?] ${f}`).join('\n')
            result += '\n'
          }

          if (status.staged.length === 0 && status.unstaged.length === 0 && status.untracked.length === 0) {
            result += 'Working directory clean - no hay cambios pendientes'
          }

          return result.trim()
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'get_git_diff',
      description: 'Obtiene el diff de cambios no commiteados',
      category: 'git' as any,
      schema: {
        type: 'object',
        properties: {
          file: {
            type: 'string',
            description: 'Ruta del archivo especifico para ver diff (opcional)'
          },
          staged: {
            type: 'boolean',
            description: 'Si true, muestra solo cambios en staging area'
          }
        }
      },
      handler: async (args: { file?: string; staged?: boolean }) => {
        try {
          const params = new URLSearchParams()
          if (args.staged) params.set('staged', 'true')
          if (args.file) params.set('file', args.file)

          const res = await apiFetch(`${API_BASE}/api/git/diff?${params}`)
          if (!res.ok) {
            const err = await res.json()
            return `Error: ${err.error}`
          }

          const data = await res.json()

          if (!data.raw || data.raw.trim() === '') {
            return 'Sin cambios'
          }

          // Return raw diff for readability
          let result = ''
          if (args.file) {
            result += `Diff de: ${args.file}\n`
          }
          if (args.staged) {
            result += '(Cambios staged)\n'
          }
          result += '\n' + data.raw

          return result
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'compare_commits',
      description: 'Compara dos commits o ramas mostrando las diferencias',
      category: 'git' as any,
      schema: {
        type: 'object',
        properties: {
          base: {
            type: 'string',
            description: 'SHA del commit o nombre de rama base (ej: main, HEAD~5)'
          },
          head: {
            type: 'string',
            description: 'SHA del commit o nombre de rama a comparar (ej: feature-branch, HEAD)'
          }
        },
        required: ['base', 'head']
      },
      handler: async (args: { base: string; head: string }) => {
        try {
          const res = await apiFetch(`${API_BASE}/api/git/compare`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(args)
          })

          if (!res.ok) {
            const err = await res.json()
            return `Error: ${err.error}`
          }

          const data = await res.json()

          let result = `Comparando: ${args.base}...${args.head}\n\n`
          result += `Estadisticas:\n`
          result += `  Archivos modificados: ${data.stats.filesChanged}\n`
          result += `  Lineas agregadas: +${data.stats.additions}\n`
          result += `  Lineas eliminadas: -${data.stats.deletions}\n\n`

          if (data.files.length > 0) {
            result += `Archivos:\n`
            result += data.files.map((f: any) => {
              const statusMap: Record<string, string> = {
                added: 'A',
                modified: 'M',
                deleted: 'D',
                renamed: 'R'
              }
              return `  [${statusMap[f.status] || '?'}] ${f.path}`
            }).join('\n')
          }

          return result
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'git_log',
      description: 'Obtiene el historial de commits del repositorio',
      category: 'git' as any,
      schema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Numero maximo de commits a retornar (default: 10)'
          },
          author: {
            type: 'string',
            description: 'Filtrar commits por autor'
          },
          since: {
            type: 'string',
            description: 'Fecha inicial en formato YYYY-MM-DD'
          }
        }
      },
      handler: async (args: { limit?: number; author?: string; since?: string }) => {
        try {
          const params = new URLSearchParams()
          params.set('limit', String(args.limit || 10))
          if (args.author) params.set('author', args.author)
          if (args.since) params.set('since', args.since)

          const res = await apiFetch(`${API_BASE}/api/git/log?${params}`)
          if (!res.ok) {
            const err = await res.json()
            return `Error: ${err.error}`
          }

          const commits = await res.json()

          if (commits.length === 0) {
            return 'Sin commits'
          }

          const result = commits.map((c: any) => {
            const date = new Date(c.timestamp * 1000)
            const dateStr = date.toLocaleDateString('es-ES', {
              year: 'numeric',
              month: 'short',
              day: 'numeric'
            })
            return `${c.shortSha} | ${dateStr} | ${c.author}\n  ${c.message}`
          }).join('\n\n')

          return `Ultimos ${commits.length} commits:\n\n${result}`
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    },
    {
      name: 'get_git_branches',
      description: 'Lista todas las ramas del repositorio',
      category: 'git' as any,
      schema: {
        type: 'object',
        properties: {}
      },
      handler: async () => {
        try {
          const res = await apiFetch(`${API_BASE}/api/git/branches`)
          if (!res.ok) {
            const err = await res.json()
            return `Error: ${err.error}`
          }

          const branches = await res.json()

          if (branches.length === 0) {
            return 'No hay ramas'
          }

          const local = branches.filter((b: any) => !b.isRemote)
          const remote = branches.filter((b: any) => b.isRemote)

          let result = ''

          if (local.length > 0) {
            result += `Ramas locales:\n`
            result += local.map((b: any) => `  ${b.isCurrent ? '* ' : '  '}${b.name}`).join('\n')
            result += '\n\n'
          }

          if (remote.length > 0) {
            result += `Ramas remotas:\n`
            result += remote.map((b: any) => `  ${b.name}`).join('\n')
          }

          return result.trim()
        } catch (e: any) {
          return `Error: ${e.message}`
        }
      }
    }
  ]
}
