import { useState, useRef, useEffect, useCallback } from 'react'
import { useParams } from 'react-router-dom'
import { apiFetch } from '@core/lib/api'
import { useAppPath } from '@core/hooks/useAppPath'
import { Button } from '@core/components/ui/button'
import { Textarea } from '@core/components/ui/textarea'
import { Badge } from '@core/components/ui/badge'
import { Skeleton } from '@core/components/ui/skeleton'
import {
  Bot,
  User,
  ChevronRight,
  Send,
  RefreshCw,
  Zap,
  Wrench,
  Code2,
  AlertTriangle,
  Plus,
  FileCode2,
} from 'lucide-react'

// ─── TYPES ────────────────────────────────────────────────────────────────────

interface Message {
  id: string
  role: 'user' | 'assistant' | 'system'
  content: string
  sources?: string[]
  tool_calls_made?: string[]
  loading?: boolean
}

// ─── MARKDOWN RENDERER ────────────────────────────────────────────────────────
// Minimal inline renderer — avoids pulling in a full markdown library.

function renderMarkdown(text: string): React.ReactNode[] {
  const parts: React.ReactNode[] = []
  let key = 0

  // Split into code blocks and text blocks
  const segments = text.split(/(```[\s\S]*?```)/g)
  for (const seg of segments) {
    if (seg.startsWith('```')) {
      const lines = seg.slice(3, -3).split('\n')
      const lang = lines[0].trim()
      const code = lines.slice(lang ? 1 : 0).join('\n')
      parts.push(
        <pre key={key++} className="bg-slate-900 text-slate-100 rounded-md p-3 my-2 overflow-auto text-xs font-mono whitespace-pre">
          {lang && <div className="text-slate-400 text-xs mb-1">{lang}</div>}
          {code}
        </pre>
      )
    } else {
      // Inline: bold, code spans, line breaks
      const inline = seg.split(/(`[^`]+`|\*\*[^*]+\*\*|\n)/g).map((chunk, i) => {
        if (chunk.startsWith('`') && chunk.endsWith('`')) {
          return <code key={i} className="bg-muted px-1 py-0.5 rounded text-xs font-mono">{chunk.slice(1, -1)}</code>
        }
        if (chunk.startsWith('**') && chunk.endsWith('**')) {
          return <strong key={i}>{chunk.slice(2, -2)}</strong>
        }
        if (chunk === '\n') return <br key={i} />
        return chunk
      })
      parts.push(<span key={key++}>{inline}</span>)
    }
  }
  return parts
}

// ─── MESSAGE BUBBLE ───────────────────────────────────────────────────────────

function MessageBubble({ message, projectId, appPath }: {
  message: Message
  projectId: string
  appPath: (p: string) => string
}) {
  const isUser = message.role === 'user'

  if (message.loading) {
    return (
      <div className="flex items-start gap-2.5">
        <div className="h-6 w-6 rounded-full bg-indigo-100 flex items-center justify-center shrink-0 mt-0.5">
          <Bot className="h-3.5 w-3.5 text-indigo-600" />
        </div>
        <div className="flex-1 space-y-1.5 pt-0.5">
          <Skeleton className="h-3 w-48" />
          <Skeleton className="h-3 w-64" />
          <Skeleton className="h-3 w-40" />
        </div>
      </div>
    )
  }

  return (
    <div className={`flex items-start gap-2.5 ${isUser ? 'flex-row-reverse' : ''}`}>
      <div className={`h-6 w-6 rounded-full flex items-center justify-center shrink-0 mt-0.5 ${isUser ? 'bg-slate-200' : 'bg-indigo-100'}`}>
        {isUser
          ? <User className="h-3.5 w-3.5 text-slate-600" />
          : <Bot className="h-3.5 w-3.5 text-indigo-600" />
        }
      </div>

      <div className={`flex-1 min-w-0 ${isUser ? 'items-end' : 'items-start'} flex flex-col`}>
        <div className={`rounded-xl px-3.5 py-2.5 max-w-[85%] text-sm leading-relaxed ${
          isUser
            ? 'bg-slate-900 text-white rounded-tr-sm'
            : 'bg-muted rounded-tl-sm'
        }`}>
          {isUser
            ? <span className="whitespace-pre-wrap">{message.content}</span>
            : <div className="prose-sm">{renderMarkdown(message.content)}</div>
          }
        </div>

        {/* Tool calls + sources */}
        {!isUser && (message.tool_calls_made?.length || message.sources?.length) ? (
          <div className="flex flex-wrap gap-1.5 mt-1.5 ml-0.5">
            {(message.tool_calls_made || []).map(tc => (
              <span key={tc} className="inline-flex items-center gap-1 text-xs bg-amber-50 border border-amber-200 text-amber-700 rounded-full px-2 py-0.5">
                <Wrench className="h-2.5 w-2.5" /> {tc}
              </span>
            ))}
            {(message.sources || []).map(src => (
              <a
                key={src}
                href={appPath(`/cil/${projectId}/chunks/${src}`)}
                className="inline-flex items-center gap-1 text-xs bg-indigo-50 border border-indigo-200 text-indigo-700 rounded-full px-2 py-0.5 hover:bg-indigo-100 transition-colors"
                title={`Open chunk: ${src}`}
              >
                <Code2 className="h-2.5 w-2.5" /> {src}
              </a>
            ))}
          </div>
        ) : null}
      </div>
    </div>
  )
}

// ─── SUGGESTION CHIPS ─────────────────────────────────────────────────────────

const SUGGESTIONS = [
  'What does the authentication middleware do?',
  'Which functions write to the embeddings table?',
  'Is it safe to refactor the createHandler function?',
  'What are the side effects of the runAgent function?',
  'Which chunks have no callers (potential dead code)?',
  'Show me undocumented chunks in this project',
]

// ─── MAIN PAGE ────────────────────────────────────────────────────────────────

export default function CILAgentPage() {
  const { id: projectId } = useParams<{ id: string }>()
  const appPath = useAppPath()
  const [messages, setMessages] = useState<Message[]>([])
  const [input, setInput] = useState('')
  const [sending, setSending] = useState(false)
  const [projectTitle, setProjectTitle] = useState('')
  const bottomRef = useRef<HTMLDivElement>(null)
  const textareaRef = useRef<HTMLTextAreaElement>(null)

  // Load project title
  useEffect(() => {
    if (!projectId) return
    apiFetch(`/api/custom_cil-project?action=get&id=${projectId}`)
      .then(r => r.json())
      .then(data => {
        const p = data?.project || data?.data?.project
        if (p?.title) setProjectTitle(p.title)
      })
      .catch(() => {})
  }, [projectId])

  // Scroll to bottom on new messages
  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages])

  const sendMessage = useCallback(async (text: string) => {
    if (!text.trim() || sending) return

    const userMsg: Message = {
      id: crypto.randomUUID(),
      role: 'user',
      content: text.trim(),
    }
    const loadingMsg: Message = {
      id: crypto.randomUUID(),
      role: 'assistant',
      content: '',
      loading: true,
    }

    setMessages(prev => [...prev, userMsg, loadingMsg])
    setInput('')
    setSending(true)

    try {
      const res = await apiFetch('/api/custom_cil-agent?action=ask', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          question: text.trim(),
          project_id: projectId,
        }),
      })
      const data = await res.json()
      const r = data?.data || data
      const answer = r?.answer || 'Sorry, I could not generate a response.'

      setMessages(prev => [
        ...prev.slice(0, -1), // remove loading
        {
          id: crypto.randomUUID(),
          role: 'assistant',
          content: answer,
          sources: r?.sources || [],
          tool_calls_made: r?.tool_calls_made || [],
        },
      ])
    } catch (err) {
      setMessages(prev => [
        ...prev.slice(0, -1),
        {
          id: crypto.randomUUID(),
          role: 'assistant',
          content: `Error: ${err instanceof Error ? err.message : String(err)}`,
        },
      ])
    } finally {
      setSending(false)
      setTimeout(() => textareaRef.current?.focus(), 50)
    }
  }, [projectId, sending])

  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      sendMessage(input)
    }
  }

  const clearConversation = () => {
    setMessages([])
    setInput('')
    textareaRef.current?.focus()
  }

  const isEmpty = messages.length === 0

  return (
    <div className="flex flex-col h-[calc(100vh-64px)]">
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-2.5 border-b bg-background shrink-0">
        <div className="flex items-center gap-2 text-sm text-muted-foreground">
          <a href={appPath('/cil')} className="hover:underline">Code Intelligence</a>
          <ChevronRight className="h-3 w-3" />
          {projectId && (
            <>
              <a href={appPath(`/cil/${projectId}/dashboard`)} className="hover:underline">{projectTitle || 'Project'}</a>
              <ChevronRight className="h-3 w-3" />
            </>
          )}
          <span className="flex items-center gap-1 text-foreground font-medium">
            <Bot className="h-3.5 w-3.5 text-indigo-500" /> CIL Agent
          </span>
        </div>

        <div className="flex items-center gap-2">
          {projectId && (
            <Badge variant="outline" className="text-xs font-mono">
              <FileCode2 className="h-3 w-3 mr-1" />
              {projectTitle || projectId.slice(0, 8)}
            </Badge>
          )}
          {!isEmpty && (
            <Button size="sm" variant="ghost" onClick={clearConversation} className="h-7 text-xs text-muted-foreground">
              <Plus className="h-3 w-3 mr-1" /> New Chat
            </Button>
          )}
        </div>
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto px-4 py-4 space-y-4">
        {isEmpty && (
          <div className="flex flex-col items-center justify-center h-full space-y-6 text-center">
            <div className="h-16 w-16 rounded-full bg-indigo-100 flex items-center justify-center">
              <Bot className="h-8 w-8 text-indigo-600" />
            </div>
            <div className="space-y-1">
              <h2 className="text-lg font-semibold">CIL Codebase Assistant</h2>
              <p className="text-sm text-muted-foreground max-w-sm">
                Ask me anything about this codebase. I'll search the indexed chunk contracts and call graph to answer accurately.
              </p>
            </div>
            <div className="flex flex-wrap gap-2 justify-center max-w-lg">
              {SUGGESTIONS.map(s => (
                <button
                  key={s}
                  className="text-xs px-3 py-1.5 rounded-full border hover:bg-muted transition-colors text-muted-foreground hover:text-foreground text-left"
                  onClick={() => sendMessage(s)}
                >
                  {s}
                </button>
              ))}
            </div>
            {!projectId && (
              <div className="flex items-center gap-1.5 text-xs text-amber-600 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2">
                <AlertTriangle className="h-3.5 w-3.5 shrink-0" />
                No project scope — searching across all indexed chunks
              </div>
            )}
          </div>
        )}

        {messages.map(msg => (
          <MessageBubble
            key={msg.id}
            message={msg}
            projectId={projectId || ''}
            appPath={appPath}
          />
        ))}

        <div ref={bottomRef} />
      </div>

      {/* Input bar */}
      <div className="border-t bg-background px-4 py-3 shrink-0">
        <div className="flex items-end gap-2 max-w-4xl mx-auto">
          <Textarea
            ref={textareaRef}
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder="Ask about a function, safe refactoring, callers, or blast radius…"
            className="min-h-[44px] max-h-[200px] resize-none text-sm"
            rows={1}
            disabled={sending}
          />
          <Button
            onClick={() => sendMessage(input)}
            disabled={!input.trim() || sending}
            className="h-11 w-11 p-0 shrink-0"
          >
            {sending
              ? <RefreshCw className="h-4 w-4 animate-spin" />
              : <Send className="h-4 w-4" />
            }
          </Button>
        </div>
        <p className="text-xs text-center text-muted-foreground mt-1.5">
          <Zap className="h-3 w-3 inline mr-1" />
          Grounded in CIL chunk contracts · Press Shift+Enter for a new line
        </p>
      </div>
    </div>
  )
}
