// ChatPanel.jsx — the §8 right-column chat surface.
//
// One feed of every message on the branch's threads (per §8.12),
// rendered in chronological order. Sub-thread messages render with a
// gutter accent and the quoted anchor preview; flag rows render with a
// flag badge. Per §8.8 each assistant message that produced changes
// carries a "↓ N changes added below" hint that flashes the matching
// cards in the change panel.

import { useEffect, useRef } from 'react'
import { MODEL_STYLES } from '../modelStyles'

function ModelLabel({ modelId, streaming }) {
  const style = MODEL_STYLES[modelId] || MODEL_STYLES.default
  return (
    <div className="chat-model-label" style={{ color: style.color }}>
      <span className="chat-model-dot" style={{ background: style.color }} />
      {style.label}{streaming ? '…' : ''}
    </div>
  )
}

function stripChangeTags(text) {
  return text
    .replace(/<change>[\s\S]*?<\/change>/g, '')
    .replace(/\n{3,}/g, '\n\n')
    .trim()
}

export default function ChatPanel({
  messages,
  threads,
  changes,
  branchName,
  isStreaming,
  contributionMode,
  onScrollToChange,
  onStartContribution,
  threadFilter,
  onThreadFilterChange,
  onResolveThread,
  forkedFromMessage,
}) {
  const bottomRef = useRef(null)

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

  const openThreads = threads.filter(t => t.state === 'open')
  const flagThreads = openThreads.filter(t => t.thread_kind === 'flag')
  const chatThreads = openThreads.filter(t => t.thread_kind === 'chat')

  return (
    <div className="chat-panel">
      <div className="chat-header">
        <div className="chat-header-row">
          <span className="chat-header-title">
            Branch chat · <strong>{branchName}</strong>
          </span>
          {forkedFromMessage && (
            <button
              type="button"
              className="chat-fork-link"
              onClick={() => onScrollToChange?.(null, forkedFromMessage)}
              title="Forked from this conversation"
            >
              ← Forked from this conversation
            </button>
          )}
        </div>
        <div className="chat-thread-disclosure">
          {chatThreads.length > 0 && (
            <span>{chatThreads.length} open thread{chatThreads.length === 1 ? '' : 's'}</span>
          )}
          {flagThreads.length > 0 && (
            <span className="chat-thread-flag-count">
              · {flagThreads.length} open flag{flagThreads.length === 1 ? '' : 's'}
            </span>
          )}
          {threadFilter && (
            <button
              type="button"
              className="chat-filter-clear"
              onClick={() => onThreadFilterChange?.(null)}
            >Clear filter</button>
          )}
        </div>
      </div>
      <div className="chat-messages">
        {messages.length === 0 ? (
          <div className="chat-empty">
            <p>
              {contributionMode
                ? 'Ask the AI about this RFC. Concrete edit suggestions land in the panel below.'
                : 'Ask the AI about this RFC. When suggestions are ready you can start a contribution.'}
            </p>
          </div>
        ) : (
          messages.map(msg => (
            <ChatMessage
              key={msg.id}
              message={msg}
              changes={changes}
              contributionMode={contributionMode}
              onScrollToChange={onScrollToChange}
              onStartContribution={onStartContribution}
              onResolveThread={onResolveThread}
              isStreaming={isStreaming}
            />
          ))
        )}
        <div ref={bottomRef} />
      </div>
    </div>
  )
}

function ChatMessage({ message, changes, contributionMode, onScrollToChange, onStartContribution, onResolveThread, isStreaming }) {
  const isUser = message.role === 'user'
  const isSystem = message.role === 'system'
  const isFlag = message.thread_kind === 'flag'
  const displayText = isUser || isSystem ? message.text : stripChangeTags(message.text)
  const messageChanges = changes.filter(c => c.source_message_id === message.id)
  const subThread = message.anchor_kind && message.anchor_kind !== 'whole-doc'

  if (isSystem) {
    return (
      <div className="chat-message system">
        <div className="chat-system-bubble">{message.text}</div>
      </div>
    )
  }

  if (isFlag) {
    return (
      <div className="chat-message flag">
        <div className="chat-flag-row">
          <span className="chat-flag-icon" title="Flag">⚑</span>
          <div className="chat-flag-content">
            <div className="chat-flag-author">@{message.author_login || '—'} flagged:</div>
            <div className="chat-flag-text">{message.flag_label || message.text}</div>
            {message.anchor_preview && (
              <div className="chat-anchor-preview">quoted: "{message.anchor_preview}"</div>
            )}
            <button
              type="button"
              className="chat-flag-resolve"
              onClick={() => onResolveThread?.(message.thread_id)}
            >Resolve</button>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className={`chat-message ${isUser ? 'user' : 'assistant'}${message.streaming ? ' streaming' : ''}${subThread ? ' in-thread' : ''}`}>
      {subThread && message.anchor_preview && (
        <div className="chat-anchor-preview">on: "{message.anchor_preview}"</div>
      )}
      {isUser && message.quote && (
        <div className="chat-quote">"{message.quote}"</div>
      )}
      {!isUser && message.model_id && (
        <ModelLabel modelId={message.model_id} streaming={message.streaming} />
      )}
      <div className="chat-bubble">
        {displayText
          ? displayText
          : message.streaming
            ? <span className="chat-thinking">Thinking…</span>
            : null}
        {message.streaming && displayText && <span className="chat-cursor" />}
      </div>
      {!isUser && !message.streaming && messageChanges.length > 0 && (
        contributionMode ? (
          <button
            type="button"
            className="chat-change-hint"
            onClick={() => onScrollToChange?.(messageChanges[0].id)}
          >
            ↓ {messageChanges.length} change{messageChanges.length === 1 ? '' : 's'} added below
          </button>
        ) : (
          <div className="chat-change-hint discuss">
            {messageChanges.length} change{messageChanges.length === 1 ? '' : 's'} proposed —{' '}
            <button className="chat-change-hint-cta" onClick={onStartContribution}>
              start a contribution to apply {messageChanges.length === 1 ? 'it' : 'them'}
            </button>
          </div>
        )
      )}
    </div>
  )
}
