import { useState, useRef, useEffect } from 'react'
import type { KeyboardEvent } from 'react'
import ReactMarkdown from 'react-markdown'
import { IconSend } from '@tabler/icons-react'
import { ToolCallCard } from './ToolCallCard'
import { MCPAppRenderer } from './MCPAppRenderer'
import { A2UIRenderer, parseA2UIBlocks } from './A2UIRenderer'
import type { ChatMessage } from '../hooks/useChat'

interface ChatPanelProps {
  messages: ChatMessage[]
  isStreaming: boolean
  onSend: (content: string) => void
  sessionId: string | null
}

// ─── Visual Block Types ────────────────────────────────────────────────────────

interface VisualBlockPayload {
  title?: string
  code: string
  data?: Record<string, unknown>
  height?: number
}

function parseVisualBlocks(content: string): VisualBlockPayload[] {
  const blocks: VisualBlockPayload[] = []
  const regex = /```visual\s*\n([\s\S]*?)```/g
  let match: RegExpExecArray | null

  while ((match = regex.exec(content)) !== null) {
    try {
      const parsed = JSON.parse(match[1]) as VisualBlockPayload
      if (parsed && typeof parsed.code === 'string') {
        blocks.push(parsed)
      }
    } catch {
      // Silently skip invalid JSON
    }
  }

  return blocks
}

// ─── VisualBlock Component ─────────────────────────────────────────────────────

const controlBtnStyle: React.CSSProperties = {
  background: 'none',
  border: '1px solid #3a3a5a',
  color: '#8888aa',
  borderRadius: '4px',
  padding: '0.15rem 0.4rem',
  fontSize: '0.75rem',
  cursor: 'pointer',
}

function VisualBlock({
  payload,
  onSend,
}: {
  payload: VisualBlockPayload
  onSend: (msg: string) => void
}) {
  const [showSource, setShowSource] = useState(false)

  function handlePopOut() {
    const w = window.open(
      '',
      '_blank',
      `width=900,height=${(payload.height ?? 300) + 120}`
    )
    if (w) {
      fetch('/api/apps/runtime')
        .then(r => r.text())
        .then(html => {
          w.document.open()
          w.document.write(html)
          w.document.close()
        })
        .catch(() => {
          w.close()
        })
    }
  }

  return (
    <div className='visual-block' style={{ margin: '0.5rem 0' }}>
      {/* Header bar */}
      <div
        style={{
          padding: '0.3rem 0.6rem',
          borderBottom: '1px solid #2a2a4a',
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          background: '#12192e',
          borderRadius: '4px 4px 0 0',
          border: '1px solid #2a2a4a',
        }}
      >
        <span style={{ color: '#7aa2f7', fontSize: '0.8rem' }}>
          {payload.title ?? 'Visual'}
        </span>
        <div style={{ display: 'flex', gap: '0.4rem' }}>
          <button
            onClick={() => setShowSource(s => !s)}
            style={controlBtnStyle}
          >
            {showSource ? 'Hide Source' : 'View Source'}
          </button>
          <button onClick={handlePopOut} style={controlBtnStyle}>
            Pop Out
          </button>
        </div>
      </div>

      {/* Source viewer */}
      {showSource && (
        <pre
          style={{
            background: '#0a0a1a',
            padding: '0.5rem',
            fontSize: '0.75rem',
            color: '#c0c0d0',
            overflowX: 'auto',
            margin: 0,
            borderLeft: '1px solid #2a2a4a',
            borderRight: '1px solid #2a2a4a',
          }}
        >
          {payload.code}
        </pre>
      )}

      {/* Runtime iframe via MCPAppRenderer */}
      <MCPAppRenderer
        resourceUri='app://runtime'
        data={{ ...payload, runtime: 'visual-artifact' }}
        onSendMessage={onSend}
      />
    </div>
  )
}

// ─── ChatPanel ─────────────────────────────────────────────────────────────────

export function ChatPanel({ messages, isStreaming, onSend, sessionId }: ChatPanelProps) {
  const [input, setInput] = useState('')
  const messagesEndRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [messages])

  function handleSend() {
    if (input.trim() && !isStreaming) {
      onSend(input.trim())
      setInput('')
    }
  }

  function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      handleSend()
    }
  }

  if (sessionId === null) {
    return (
      <div className='chat-panel'>
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            height: '100%',
          }}
        >
          <span style={{ color: '#6a6a8a', fontSize: '1.1rem' }}>
            Select or create a session to start researching
          </span>
        </div>
      </div>
    )
  }

  return (
    <div className='chat-panel'>
      <div className='chat-messages'>
        {messages.map(message => (
          <div key={message.id} className={`chat-message ${message.role}`}>
            {message.role === 'assistant' ? (
              <div>
                <ReactMarkdown>{message.content}</ReactMarkdown>

                {/* A2UI interactive blocks */}
                {parseA2UIBlocks(message.content).map((block, i) => (
                  <A2UIRenderer
                    key={i}
                    block={block}
                    onAction={(action, data) =>
                      onSend(`[${action}] ${JSON.stringify(data)}`)
                    }
                  />
                ))}

                {/* Visual artifact blocks */}
                {parseVisualBlocks(message.content).map((payload, i) => (
                  <VisualBlock key={i} payload={payload} onSend={onSend} />
                ))}

                {/* Tool call cards / MCP app renderers */}
                {message.toolCalls?.map(tc =>
                  tc._meta?.ui?.resourceUri ? (
                    <MCPAppRenderer
                      key={tc.id}
                      resourceUri={tc._meta.ui.resourceUri}
                      data={tc.structuredContent ?? {}}
                      csp={tc._meta.ui.csp}
                      onSendMessage={(content) => onSend(content)}
                    />
                  ) : (
                    <ToolCallCard key={tc.id} toolCall={tc} />
                  )
                )}
              </div>
            ) : (
              <div>{message.content}</div>
            )}
          </div>
        ))}
        {isStreaming && messages.length > 0 && <div>Researching...</div>}
        <div ref={messagesEndRef} />
      </div>
      <div className='chat-input-area'>
        <input
          placeholder='Ask a research question...'
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={handleKeyDown}
          disabled={isStreaming}
          autoFocus
        />
        <button onClick={handleSend} disabled={isStreaming || !input.trim()}>
          <IconSend size={18} />
        </button>
      </div>
    </div>
  )
}
