/* global React */
const { useState, useEffect, useRef } = React;

// ===================== CHAT THREAD =====================
function ChatThread({ thread, streaming, editingId, setEditingId, editMessage, convo }) {
  const scrollRef = useRef();
  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [thread, streaming]);

  return (
    <div className="thread-wrap" ref={scrollRef}>
      <div className="thread">
        <header className="thread-header">
          <h2 className="thread-title">{convo?.title || "Untitled conversation"}</h2>
          <div className="thread-meta">{convo?.date} · {thread.length} messages</div>
        </header>

        {thread.map((m, i) => (
          <Message
            key={m.id}
            msg={m}
            streaming={streaming && i === thread.length - 1 && m.role === "assistant"}
            editing={editingId === m.id}
            onStartEdit={() => setEditingId(m.id)}
            onCancelEdit={() => setEditingId(null)}
            onSaveEdit={(t) => editMessage(m.id, t)}
          />
        ))}

      </div>
    </div>
  );
}

function Message({ msg, streaming, editing, onStartEdit, onCancelEdit, onSaveEdit }) {
  const [draft, setDraft] = useState(msg.text);
  useEffect(() => { setDraft(msg.text); }, [msg.text]);

  if (msg.role === "user") {
    return (
      <article className="msg msg-user">
        <div className="msg-rail" aria-hidden="true" />
        <div className="msg-body">
          <div className="msg-head">
            <span className="msg-author">You</span>
            <button className="msg-edit" onClick={editing ? onCancelEdit : onStartEdit}>
              {editing ? "Cancel" : "Edit"}
            </button>
          </div>
          {editing ? (
            <div className="msg-edit-wrap">
              <textarea className="msg-edit-input" value={draft} onChange={(e) => setDraft(e.target.value)} autoFocus rows={Math.max(2, Math.ceil(draft.length / 60))} />
              <div className="msg-edit-actions">
                <button className="ghost-btn" onClick={onCancelEdit}>Cancel</button>
                <button className="primary-btn" onClick={() => onSaveEdit(draft)}>Save</button>
              </div>
            </div>
          ) : (
            <p className="msg-text user-text">{msg.text}</p>
          )}
        </div>
      </article>
    );
  }

  return (
    <article className="msg msg-asst">
      <div className="msg-mark" aria-hidden="true">
        <svg viewBox="0 0 24 24" width="14" height="14"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" strokeWidth="1.4"/><circle cx="12" cy="12" r="3" fill="currentColor"/></svg>
      </div>
      <div className="msg-body">
        <div className="msg-head">
          <span className="msg-author">Shannon</span>
          {streaming && <span className="streaming-dot"><span/><span/><span/></span>}
        </div>
        <RichText text={msg.text} streaming={streaming} />
        {msg.code && !streaming && <CodeBlock lang={msg.code.lang} body={msg.code.body} />}
        {!streaming && msg.text && (
          <div className="msg-tools">
            <button className="tool-btn" title="Copy"><svg viewBox="0 0 24 24" width="13" height="13"><rect x="8" y="8" width="12" height="12" rx="2" fill="none" stroke="currentColor" strokeWidth="1.5"/><path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3" fill="none" stroke="currentColor" strokeWidth="1.5"/></svg></button>
            <button className="tool-btn" title="Read aloud"><svg viewBox="0 0 24 24" width="13" height="13"><path d="M5 9v6h4l5 4V5L9 9H5Z" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M17 8a5 5 0 0 1 0 8" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg></button>
            <button className="tool-btn" title="Bookmark"><svg viewBox="0 0 24 24" width="13" height="13"><path d="M6 3h12v18l-6-4-6 4V3Z" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></svg></button>
          </div>
        )}
      </div>
    </article>
  );
}

function RichText({ text, streaming }) {
  // Split into paragraphs; detect numbered lists
  const paras = text.split("\n\n");
  return (
    <div className="rich">
      {paras.map((p, i) => {
        const lines = p.split("\n");
        const isList = lines.every(l => /^\s*\d+\.\s/.test(l) || /^\s*-\s/.test(l));
        if (isList && lines.length > 1) {
          const isNum = /^\s*\d+\./.test(lines[0]);
          const Tag = isNum ? "ol" : "ul";
          return (
            <Tag key={i} className="rich-list">
              {lines.map((l, j) => <li key={j}>{l.replace(/^\s*(\d+\.|-)\s*/, "")}</li>)}
            </Tag>
          );
        }
        return <p key={i} className="rich-p">{p}{streaming && i === paras.length - 1 ? <span className="caret"/> : null}</p>;
      })}
    </div>
  );
}

function CodeBlock({ lang, body }) {
  const [copied, setCopied] = useState(false);
  const onCopy = () => {
    try { navigator.clipboard.writeText(body); } catch (e) {}
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };
  // very small "syntax tint": comments italic-muted, strings ochre
  const lines = body.split("\n").map((line, i) => {
    const parts = [];
    let rest = line;
    const commentIdx = rest.indexOf("#");
    if (commentIdx >= 0) {
      parts.push(<span key="pre">{rest.slice(0, commentIdx)}</span>);
      parts.push(<span key="cm" className="tk-comment">{rest.slice(commentIdx)}</span>);
    } else {
      // string highlight (very rough)
      const tokens = rest.split(/('[^']*'|"[^"]*")/);
      tokens.forEach((tok, k) => {
        if (/^['"]/.test(tok)) parts.push(<span key={k} className="tk-string">{tok}</span>);
        else parts.push(<span key={k}>{tok}</span>);
      });
    }
    return <div key={i} className="code-line"><span className="code-num">{i + 1}</span><span className="code-content">{parts}</span></div>;
  });
  return (
    <div className="code-block">
      <div className="code-head">
        <span className="code-lang">{lang}</span>
        <button className="code-copy" onClick={onCopy}>
          {copied ? "Copied" : "Copy"}
        </button>
      </div>
      <pre className="code-body">{lines}</pre>
    </div>
  );
}

window.ChatThread = ChatThread;
