import { useState, useRef, useEffect, useCallback } from 'react'
import { useI18n } from '../i18n'

function renderContent(text) {
  const parts = []
  const codeBlockRegex = /(```[\s\S]*?```)/g
  let match
  let lastIndex = 0
  while ((match = codeBlockRegex.exec(text)) !== null) {
    if (match.index > lastIndex) {
      parts.push({ type: 'text', content: text.slice(lastIndex, match.index) })
    }
    const full = match[1]
    const firstNewline = full.indexOf('\n')
    const lang = firstNewline > -1 ? full.slice(3, firstNewline).trim() : ''
    const code = firstNewline > -1 ? full.slice(firstNewline + 1, -3) : full.slice(3, -3)
    parts.push({ type: 'code', lang, content: code })
    lastIndex = match.index + full.length
  }
  if (lastIndex < text.length) {
    parts.push({ type: 'text', content: text.slice(lastIndex) })
  }
  return parts
}

function formatText(text) {
  return text
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>')
    .replace(/^### (.+)$/gm, '<h4 class="msg-h4">$1</h4>')
    .replace(/^## (.+)$/gm, '<h3 class="msg-h3">$1</h3>')
    .replace(/^\s*[-*] (.+)$/gm, '<span class="msg-bullet">$1</span>')
    .replace(/^\s*(\d+)[.)] (.+)$/gm, '<span class="msg-step"><span class="msg-step-num">$1</span>$2</span>')
}

function FeedItem({ msg }) {
  const isUser = msg.role === 'user'
  const isSystem = msg.role === 'system'

  const roleLabel = isUser ? null : isSystem ? null : (
    <div className="feed-avatar">
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
        <path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/>
      </svg>
    </div>
  )

  const timeStr = msg.time ? new Date(msg.time).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : ''

  if (isSystem) {
    return (
      <div className="feed-item system">
        <div className="feed-system-badge" />
        <div className="feed-system-text">{msg.content}</div>
        {timeStr && <span className="feed-time">{timeStr}</span>}
      </div>
    )
  }

  return (
    <div className={`feed-item ${msg.role}`}>
      {roleLabel}
      <div className="feed-body">
        <div className="feed-header">
          <span className="feed-role">{isUser ? 'Vous' : 'IA'}</span>
          {timeStr && <span className="feed-time">{timeStr}</span>}
        </div>
        <div className="feed-content">
          {renderContent(msg.content).map((part, i) =>
            part.type === 'code' ? (
              <div key={i} className="studio-code-block">
                {part.lang && <div className="studio-code-lang">{part.lang}</div>}
                <pre><code>{part.content}</code></pre>
              </div>
            ) : (
              <span key={i} dangerouslySetInnerHTML={{ __html: formatText(part.content) }} />
            )
          )}
        </div>
      </div>
    </div>
  )
}

function StreamingItem({ content }) {
  return (
    <div className="feed-item assistant">
      <div className="feed-avatar">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/>
        </svg>
      </div>
      <div className="feed-body">
        <div className="feed-header">
          <span className="feed-role">IA</span>
        </div>
        <div className="feed-content">
          {renderContent(content).map((part, i) =>
            part.type === 'code' ? (
              <div key={i} className="studio-code-block">
                {part.lang && <div className="studio-code-lang">{part.lang}</div>}
                <pre><code>{part.content}</code></pre>
              </div>
            ) : (
              <span key={i} dangerouslySetInnerHTML={{ __html: formatText(part.content) }} />
            )
          )}
          <span className="studio-cursor" />
        </div>
      </div>
    </div>
  )
}

export default function Studio({ api }) {
  const { t } = useI18n()
  const [messages, setMessages] = useState([])
  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)
  const [streaming, setStreaming] = useState('')
  const [loaded, setLoaded] = useState(false)
  const messagesEnd = useRef(null)
  const textareaRef = useRef(null)

  useEffect(() => {
    api.getChatHistory().then(data => {
      if (data.messages && data.messages.length > 0) {
        setMessages(data.messages)
      } else {
        setMessages([
          { id: 'welcome', role: 'system', content: t('studio.welcomeNew'), time: new Date().toISOString() },
        ])
      }
      setLoaded(true)
    }).catch(() => {
      setMessages([
        { id: 'welcome', role: 'system', content: t('studio.welcomeNew'), time: new Date().toISOString() },
      ])
      setLoaded(true)
    })
  }, [])

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

  useEffect(() => {
    if (textareaRef.current) {
      textareaRef.current.style.height = 'auto'
      textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 200) + 'px'
    }
  }, [input])

  const handleClear = useCallback(async () => {
    try {
      await api.clearChat()
      setMessages([
        { id: 'clear-' + Date.now(), role: 'system', content: t('studio.cleared'), time: new Date().toISOString() },
      ])
    } catch {}
  }, [api, t])

  const handleSend = useCallback(async () => {
    if (!input.trim() || loading) return
    const text = input.trim()
    setInput('')

    if (text === '/clear') {
      handleClear()
      return
    }

    const userMsg = { id: Date.now().toString(), role: 'user', content: text, time: new Date().toISOString() }
    setMessages(prev => [...prev, userMsg])
    setLoading(true)
    setStreaming('')

    try {
      let accumulated = ''
      await api.sendChat(text, true, (partial) => {
        accumulated = partial
        setStreaming(partial)
      })

      const finalContent = accumulated || t('studio.noResponse')
      setMessages(prev => [...prev, {
        id: (Date.now() + 1).toString(),
        role: 'assistant',
        content: finalContent,
        time: new Date().toISOString(),
      }])
    } catch (err) {
      setMessages(prev => [...prev, {
        id: (Date.now() + 1).toString(),
        role: 'system',
        content: `${t('studio.error')}: ${err.message}`,
        time: new Date().toISOString(),
      }])
    } finally {
      setLoading(false)
      setStreaming('')
    }
  }, [input, loading, api, t, handleClear])

  const handleKeyDown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault()
      handleSend()
    }
  }

  if (!loaded) {
    return (
      <div className="studio-feed-layout">
        <div className="studio-feed">
          <div className="feed-loading">
            <div className="studio-thinking"><span /><span /><span /></div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="studio-feed-layout">
      <div className="studio-feed">
        {messages.map(msg => (
          <FeedItem key={msg.id} msg={msg} />
        ))}
        {streaming && <StreamingItem content={streaming} />}
        {loading && !streaming && (
          <div className="feed-item assistant">
            <div className="feed-avatar">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/>
              </svg>
            </div>
            <div className="feed-body">
              <div className="feed-content">
                <div className="studio-thinking"><span /><span /><span /></div>
              </div>
            </div>
          </div>
        )}
        <div ref={messagesEnd} />
      </div>

      <div className="studio-input-area">
        <div className="studio-input-row">
          <textarea
            ref={textareaRef}
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder={t('studio.placeholderNew')}
            disabled={loading}
            rows={1}
          />
          <button
            className="studio-send-btn"
            onClick={handleSend}
            disabled={loading || !input.trim()}
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
            </svg>
          </button>
        </div>
        <div className="studio-input-hint">
          {t('studio.inputHint')} &middot; /clear
        </div>
      </div>
    </div>
  )
}
