import { optionsResponse, notFoundResponse } from '../utils/cors'
import { handleHistory } from './history'
import { handleConfig, handleHealth } from './config'
import { handleWebMCPToken, handleWebMCPRequestToken } from './webmcp'
import { handleComponents, handleComponentById, handleComponentUsage } from './components'
import { handleFsComponents, handleFsComponentByName } from './fs-components'
import { handleThemes, handleActiveTheme, handleDesignTokens, handleThemeById, handleThemeExport } from './themes'
import { handleCanvas, handleCanvasById, handleToolbarCanvas, handleDefaultCanvas, handleCanvasComponents, handleCanvasComponentById } from './canvas'
import { handleGiteaRepo, handleGiteaTree, handleGiteaFile } from './gitea'
import { handleTables, handleStats, handleTableSchema, handleTableData, handleQuery } from './database'
import { handleWhisperRoutes } from './whisper'
import { handleRecordingsRoutes } from './recordings'
import { handleClaudeStatus } from './claude-status'
import { handleClaudeHook } from './claude-hook'
import { handleClaudePermission, handleClaudePermissionRespond, handleClaudePermissionList } from './claude-permission'
import { handleSnapshots, handleSnapshotById } from './snapshots'
import { handleGitStatus, handleGitDiff, handleGitLog, handleGitLogCommit, handleGitCompare, handleGitBranches, handleGitCurrentBranch, handleGitTree, handleGitFile } from './git'
import {
  handleAgents, handleAgentsFile,
  handleAgentsConfig, handleAgentsKnownTools, handleAgentsSkills,
  handleAgentsPlugins, handleAgentsMcpJson,
  handleAgentsConfigPermissions, handleAgentsConfigHooks, handleAgentsConfigMcp
} from './agents'
import { handleTranscript, handleTranscriptSessions, handleTranscriptActive, handleClaudeStats, handleClaudeUsage } from './transcript'
import { handleTranscriptDebugSessions, handleTranscriptDebugRaw, handleTranscriptDebugSend, handleTranscriptDebugStatus } from './transcript-debug'
import {
  handleHooksApprovalPermission, handleHooksApprovalPlan,
  handleHooksApprovalRespond, handleHooksApprovalRespondPlan,
  handleHooksApprovalIgnore, handleHooksApprovalList
} from './hooks-approval'

export async function handleRequest(req: Request): Promise<Response> {
  const url = new URL(req.url)
  const path = url.pathname

  // CORS preflight
  if (req.method === 'OPTIONS') {
    return optionsResponse()
  }

  // Health
  if (path === '/api/health') {
    return handleHealth()
  }

  // History
  if (path === '/api/history') {
    const res = await handleHistory(req, url)
    if (res) return res
  }

  // Config
  if (path === '/api/config') {
    const res = await handleConfig(req, url)
    if (res) return res
  }

  // WebMCP Token (for polling - legacy)
  if (path === '/api/webmcp-token') {
    const res = await handleWebMCPToken(req)
    if (res) return res
  }

  // WebMCP Request Token (direct request to WebMCP server)
  if (path === '/api/webmcp-request-token') {
    const res = await handleWebMCPRequestToken(req)
    if (res) return res
  }

  // Claude Code status (thinking/idle)
  if (path === '/api/claude-status') {
    const res = await handleClaudeStatus(req)
    if (res) return res
  }

  // Claude Code hook (rich stdin data forwarding)
  if (path === '/api/claude-hook') {
    const res = await handleClaudeHook(req)
    if (res) return res
  }

  // Claude Code permission request/respond
  if (path === '/api/claude-permission') {
    if (req.method === 'GET') {
      const res = await handleClaudePermissionList(req)
      if (res) return res
    } else {
      const res = await handleClaudePermission(req)
      if (res) return res
    }
  }

  if (path === '/api/claude-permission-respond') {
    const res = await handleClaudePermissionRespond(req)
    if (res) return res
  }

  // Components
  if (path === '/api/components') {
    const res = await handleComponents(req)
    if (res) return res
  }

  // Component usage
  const componentUsageMatch = path.match(/^\/api\/components\/([^/]+)\/usage$/)
  if (componentUsageMatch && req.method === 'GET') {
    return handleComponentUsage(componentUsageMatch[1])
  }

  // Component by ID
  if (path.startsWith('/api/components/') && !path.includes('/usage')) {
    const id = path.split('/').pop()!
    const res = await handleComponentById(req, id)
    if (res) return res
  }

  // Filesystem components
  if (path === '/api/fs-components') {
    const res = handleFsComponents(req)
    if (res) return res
  }

  if (path.startsWith('/api/fs-components/')) {
    const folderName = path.split('/').pop()!
    const res = handleFsComponentByName(req, folderName)
    if (res) return res
  }

  // Themes
  if (path === '/api/themes') {
    const res = await handleThemes(req)
    if (res) return res
  }

  if (path === '/api/themes/active') {
    return handleActiveTheme()
  }

  if (path === '/api/design-tokens') {
    return handleDesignTokens()
  }

  // Theme export
  if (path.startsWith('/api/themes/export/')) {
    const id = path.split('/').pop()!
    if (req.method === 'GET') {
      return handleThemeExport(id)
    }
  }

  // Theme by ID
  if (path.startsWith('/api/themes/') && !path.includes('/active') && !path.includes('/export')) {
    const pathParts = path.split('/')
    const id = pathParts[3]
    const action = pathParts[4]
    const res = await handleThemeById(req, id, action)
    if (res) return res
  }

  // Canvas toolbar
  if (path === '/api/canvas/toolbar') {
    return handleToolbarCanvas()
  }

  // Canvas default
  if (path === '/api/canvas/default') {
    return handleDefaultCanvas()
  }

  // Canvas list/create
  if (path === '/api/canvas') {
    const res = await handleCanvas(req)
    if (res) return res
  }

  // Canvas components
  const canvasComponentsMatch = path.match(/^\/api\/canvas\/([^/]+)\/components\/?$/)
  if (canvasComponentsMatch) {
    const res = await handleCanvasComponents(req, canvasComponentsMatch[1])
    if (res) return res
  }

  // Canvas component by ID
  const canvasComponentMatch = path.match(/^\/api\/canvas\/([^/]+)\/components\/([^/]+)$/)
  if (canvasComponentMatch) {
    const res = await handleCanvasComponentById(req, canvasComponentMatch[1], canvasComponentMatch[2])
    if (res) return res
  }

  // Canvas by ID
  if (path.startsWith('/api/canvas/') && !path.includes('/components')) {
    const pathParts = path.split('/')
    const id = pathParts[3]
    const action = pathParts[4]
    const res = await handleCanvasById(req, id, action)
    if (res) return res
  }

  // Snapshots
  if (path === '/api/snapshots') {
    const res = await handleSnapshots(req)
    if (res) return res
  }

  if (path.startsWith('/api/snapshots/')) {
    const id = path.split('/').pop()!
    const res = await handleSnapshotById(req, id)
    if (res) return res
  }

  // Gitea
  if (path === '/api/gitea/repo' && req.method === 'POST') {
    return handleGiteaRepo(req)
  }

  if (path === '/api/gitea/tree' && req.method === 'POST') {
    return handleGiteaTree(req)
  }

  if (path === '/api/gitea/file' && req.method === 'POST') {
    return handleGiteaFile(req)
  }

  // Database Explorer
  if (path === '/api/database/tables') {
    return handleTables()
  }

  if (path === '/api/database/stats') {
    return handleStats()
  }

  // Table schema
  const tableSchemaMatch = path.match(/^\/api\/database\/tables\/([^/]+)\/schema$/)
  if (tableSchemaMatch && req.method === 'GET') {
    return handleTableSchema(decodeURIComponent(tableSchemaMatch[1]))
  }

  // Table data
  const tableDataMatch = path.match(/^\/api\/database\/tables\/([^/]+)\/data$/)
  if (tableDataMatch && req.method === 'GET') {
    return handleTableData(decodeURIComponent(tableDataMatch[1]), url)
  }

  // Database query
  if (path === '/api/database/query' && req.method === 'POST') {
    return handleQuery(req)
  }

  // Whisper (GPU speech-to-text)
  if (path.startsWith('/api/whisper/')) {
    const res = await handleWhisperRoutes(req)
    if (res) return res
  }

  // Voice recordings (for training custom models)
  if (path.startsWith('/api/recordings')) {
    const res = await handleRecordingsRoutes(req)
    if (res) return res
  }

  // Git
  if (path === '/api/git/status' && req.method === 'GET') {
    return handleGitStatus()
  }

  if (path === '/api/git/diff' && req.method === 'GET') {
    return handleGitDiff(url)
  }

  if (path === '/api/git/log' && req.method === 'GET') {
    return handleGitLog(url)
  }

  const gitLogCommitMatch = path.match(/^\/api\/git\/log\/([a-f0-9]+)$/)
  if (gitLogCommitMatch && req.method === 'GET') {
    return handleGitLogCommit(gitLogCommitMatch[1])
  }

  if (path === '/api/git/compare' && req.method === 'POST') {
    return handleGitCompare(req)
  }

  if (path === '/api/git/branches' && req.method === 'GET') {
    return handleGitBranches()
  }

  if (path === '/api/git/branch/current' && req.method === 'GET') {
    return handleGitCurrentBranch()
  }

  if (path === '/api/git/tree' && req.method === 'GET') {
    return handleGitTree(url)
  }

  if (path === '/api/git/file' && req.method === 'GET') {
    return handleGitFile(url)
  }

  // Claude usage limits (estimated)
  if (path === '/api/claude-usage') {
    return handleClaudeUsage()
  }

  // Claude stats (global)
  if (path === '/api/claude-stats') {
    return handleClaudeStats()
  }

  // Transcript
  if (path === '/api/transcript/active' && req.method === 'GET') {
    return handleTranscriptActive(req, url)
  }

  if (path === '/api/transcript/sessions' && req.method === 'GET') {
    return handleTranscriptSessions()
  }

  if (path === '/api/transcript/latest' && req.method === 'GET') {
    return handleTranscript(req, url, 'latest')
  }

  const transcriptMatch = path.match(/^\/api\/transcript\/([a-f0-9-]+)$/)
  if (transcriptMatch && req.method === 'GET') {
    return handleTranscript(req, url, transcriptMatch[1])
  }

  // Transcript Debug
  if (path === '/api/transcript-debug/sessions' && req.method === 'GET') {
    return handleTranscriptDebugSessions(url)
  }

  if (path === '/api/transcript-debug/send' && req.method === 'POST') {
    return handleTranscriptDebugSend(req)
  }

  if (path === '/api/transcript-debug/status' && req.method === 'GET') {
    return handleTranscriptDebugStatus(url)
  }

  const transcriptDebugRawMatch = path.match(/^\/api\/transcript-debug\/([a-f0-9-]+)\/raw$/)
  if (transcriptDebugRawMatch && req.method === 'GET') {
    return handleTranscriptDebugRaw(transcriptDebugRawMatch[1], url)
  }

  // Hooks Approval (long-poll for permission/plan decisions)
  if (path === '/api/hooks-approval') {
    if (req.method === 'GET') {
      const res = await handleHooksApprovalList(req)
      if (res) return res
    }
  }

  if (path === '/api/hooks-approval/permission' && req.method === 'POST') {
    const res = await handleHooksApprovalPermission(req)
    if (res) return res
  }

  if (path === '/api/hooks-approval/plan' && req.method === 'POST') {
    const res = await handleHooksApprovalPlan(req)
    if (res) return res
  }

  if (path === '/api/hooks-approval/respond' && req.method === 'POST') {
    const res = await handleHooksApprovalRespond(req)
    if (res) return res
  }

  if (path === '/api/hooks-approval/respond-plan' && req.method === 'POST') {
    const res = await handleHooksApprovalRespondPlan(req)
    if (res) return res
  }

  if (path === '/api/hooks-approval/ignore' && req.method === 'POST') {
    const res = await handleHooksApprovalIgnore(req)
    if (res) return res
  }

  // Agents
  if (path === '/api/agents' && req.method === 'GET') {
    return handleAgents(req)
  }

  if (path === '/api/agents/config' && req.method === 'GET') {
    const res = await handleAgentsConfig(req, url)
    if (res) return res
  }

  if (path === '/api/agents/known-tools' && req.method === 'GET') {
    const res = await handleAgentsKnownTools(req)
    if (res) return res
  }

  if (path === '/api/agents/skills' && req.method === 'GET') {
    const res = await handleAgentsSkills(req, url)
    if (res) return res
  }

  if (path === '/api/agents/plugins' && req.method === 'GET') {
    const res = await handleAgentsPlugins(req)
    if (res) return res
  }

  if (path === '/api/agents/mcp-json' && req.method === 'GET') {
    const res = await handleAgentsMcpJson(req)
    if (res) return res
  }

  if (path === '/api/agents/config/permissions' && req.method === 'POST') {
    const res = await handleAgentsConfigPermissions(req)
    if (res) return res
  }

  if (path === '/api/agents/config/hooks' && req.method === 'POST') {
    const res = await handleAgentsConfigHooks(req)
    if (res) return res
  }

  if (path === '/api/agents/config/mcp' && req.method === 'POST') {
    const res = await handleAgentsConfigMcp(req)
    if (res) return res
  }

  if (path === '/api/agents/file') {
    const res = await handleAgentsFile(req, url)
    if (res) return res
  }

  return notFoundResponse()
}
