// Oracle Chat Interface — Stoic Oracle with counselor switching

const RAILWAY_URL = (typeof window !== 'undefined' && window.__ARETE_CONFIG__ && window.__ARETE_CONFIG__.railwayUrl)
  || 'https://arete-app-production.up.railway.app';

const COUNSELORS = [
  { id: 'oracle',    name: 'Oracle',         fullName: 'The Oracle',      author: null,
    label: 'The unified tradition', initial: 'S', bg: '#c9a84c', textColor: '#0a1020' },
  { id: 'marcus',    name: 'Marcus Aurelius', fullName: 'Marcus Aurelius', author: 'Marcus Aurelius',
    label: 'Emperor · Philosopher', initial: 'M', bg: '#2d1b4e', textColor: '#c9a84c' },
  { id: 'epictetus', name: 'Epictetus',       fullName: 'Epictetus',       author: 'Epictetus',
    label: 'Teacher · Freed slave', initial: 'E', bg: '#0f2744', textColor: '#c9a84c' },
  { id: 'seneca',    name: 'Seneca',          fullName: 'Seneca',          author: 'Seneca',
    label: 'Advisor · Essayist',    initial: 'S', bg: '#0f2e1a', textColor: '#c9a84c' },
];

const SUGGESTED = [
  "How do I stop caring what others think?",
  "What should I do when I'm angry?",
  "How do I face something I'm afraid of?",
];

const SWITCH_PATTERNS = [
  { re: /\b(speak|talk|switch)\s*(to|with)?\s*marcus(\s+aurelius)?\b/i,           id: 'marcus'    },
  { re: /\b(speak|talk|switch)\s*(to|with)?\s*epictetus\b/i,                      id: 'epictetus' },
  { re: /\b(speak|talk|switch)\s*(to|with)?\s*seneca\b/i,                         id: 'seneca'    },
  { re: /\b(back\s+to\s+oracle|speak\s+with\s+oracle|talk\s+to\s+oracle)\b/i,     id: 'oracle'    },
];

const PORTRAIT_SIZE = { lg: [64,26], md: [38,15], sm: [28,11], xs: [20,9] };

let _id = 0;
function mkMsg(fields) { return { id: ++_id, ...fields }; }

// ─── Portrait circle ──────────────────────────────────────────────────────────
function Portrait({ c, size }) {
  const [d, f] = PORTRAIT_SIZE[size] || PORTRAIT_SIZE.md;
  return (
    <div style={{
      width: d, height: d, borderRadius: '50%', flexShrink: 0,
      background: c.bg, display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <span style={{
        fontFamily: "'Cormorant Garamond', serif",
        fontWeight: 600, fontSize: f, lineHeight: 1,
        color: c.textColor, letterSpacing: 0,
      }}>{c.initial}</span>
    </div>
  );
}

// ─── Main Page ────────────────────────────────────────────────────────────────
function OraclePage() {
  const [messages,    setMessages]    = React.useState([]);
  const [counselor,   setCounselor]   = React.useState(COUNSELORS[0]);
  const [input,       setInput]       = React.useState('');
  const [loading,     setLoading]     = React.useState(false);
  const [rateLimited, setRateLimited] = React.useState(false);
  const [remaining,   setRemaining]   = React.useState(15);
  const [showPicker,  setShowPicker]  = React.useState(false);

  const bottomRef   = React.useRef(null);
  const textareaRef = React.useRef(null);

  // Scroll to bottom on new messages / typing indicator
  React.useEffect(() => {
    if (bottomRef.current) {
      bottomRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  }, [messages, loading]);

  // Auto-resize textarea (max 4 lines ≈ 112px)
  React.useEffect(() => {
    const ta = textareaRef.current;
    if (!ta) return;
    ta.style.height = 'auto';
    ta.style.height = Math.min(ta.scrollHeight, 112) + 'px';
  }, [input]);

  function switchCounselor(next) {
    if (next.id === counselor.id) return;
    setCounselor(next);
    setMessages(prev => [...prev, mkMsg({
      type: 'divider',
      content: `You are now speaking with ${next.fullName}`,
    })]);
  }

  function detectSwitch(text) {
    for (const { re, id } of SWITCH_PATTERNS) {
      if (re.test(text)) return COUNSELORS.find(c => c.id === id) || null;
    }
    return null;
  }

  async function handleSend(questionText) {
    const q = (typeof questionText === 'string' ? questionText : input).trim();
    if (!q || loading || rateLimited) return;

    // Pure switch command — switch counselor, don't call API
    const switchTo = detectSwitch(q);
    if (switchTo && switchTo.id !== counselor.id) {
      switchCounselor(switchTo);
      setInput('');
      return;
    }

    const active = counselor; // capture for async closure

    // Build history: last 6 user/assistant msgs (3 exchanges)
    const hist = messages
      .filter(m => m.type === 'user' || m.type === 'assistant')
      .slice(-6)
      .map(m => ({ role: m.type === 'user' ? 'user' : 'assistant', content: m.content }));

    setMessages(prev => [...prev, mkMsg({ type: 'user', content: q })]);
    setInput('');
    setLoading(true);

    try {
      const res = await fetch(RAILWAY_URL + '/oracle', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ question: q, author: active.author, history: hist }),
      });

      if (res.status === 429) {
        setRateLimited(true);
        setLoading(false);
        setMessages(prev => [...prev, mkMsg({
          type: 'system', variant: 'ratelimit',
          content: "You've reached your 15 free queries for today. Come back tomorrow.",
        })]);
        return;
      }

      if (!res.ok) throw new Error('The Oracle is silent. Please try again.');

      const data = await res.json();
      if (data.remaining !== undefined) setRemaining(data.remaining);
      setLoading(false);

      setMessages(prev => {
        const msg = mkMsg({
          type: 'assistant',
          content: data.answer || data.response || '',
          sources: data.sources || [],
          counselor: active,
        });
        const next = [...prev, msg];
        // Inject CTA card after every 4th assistant message
        const aCount = next.filter(m => m.type === 'assistant').length;
        if (aCount > 0 && aCount % 4 === 0) next.push(mkMsg({ type: 'cta' }));
        return next;
      });

    } catch (err) {
      setLoading(false);
      setMessages(prev => [...prev, mkMsg({
        type: 'system', variant: 'error',
        content: err.message || 'Something went wrong. Please try again.',
      })]);
    }
  }

  function handleKeyDown(e) {
    if (e.key === 'Enter' && !e.shiftKey && window.innerWidth >= 768) {
      e.preventDefault();
      handleSend();
    }
  }

  return (
    <div className="oc-page">
      <OracleTopbar />
      <div className="oc-body">

        {/* ── Desktop Sidebar ── */}
        <aside className="oc-sidebar">
          <div className="oc-sidebar-label">The Portal</div>
          <div className="oc-sidebar-sub">Peer into the past</div>
          <div className="oc-counselor-list">
            {COUNSELORS.map(c => (
              <button
                key={c.id}
                className={'oc-counselor-card' + (counselor.id === c.id ? ' oc-active' : '')}
                onClick={() => switchCounselor(c)}
              >
                <Portrait c={c} size="md" />
                <div className="oc-counselor-info">
                  <div className="oc-counselor-name">{c.name}</div>
                  <div className="oc-counselor-lbl">{c.label}</div>
                </div>
              </button>
            ))}
          </div>
          <div className="oc-sep" />
          <div className="oc-remaining-text">
            {rateLimited
              ? 'Daily limit reached'
              : `${remaining} quer${remaining === 1 ? 'y' : 'ies'} remaining today`}
          </div>
        </aside>

        {/* ── Main Chat ── */}
        <main className="oc-main">

          {/* Mobile header */}
          <div className="oc-mob-header">
            <button className="oc-mob-btn" onClick={() => setShowPicker(p => !p)}>
              <Portrait c={counselor} size="sm" />
              <span className="oc-mob-name">{counselor.name}</span>
              <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                <path d="M6 9l6 6 6-6"/>
              </svg>
            </button>
          </div>

          {/* Mobile bottom sheet picker */}
          {showPicker && (
            <div className="oc-picker-backdrop" onClick={() => setShowPicker(false)}>
              <div className="oc-picker" onClick={e => e.stopPropagation()}>
                <div className="oc-picker-title">Choose your counselor</div>
                {COUNSELORS.map(c => (
                  <button
                    key={c.id}
                    className={'oc-picker-item' + (counselor.id === c.id ? ' oc-active' : '')}
                    onClick={() => { switchCounselor(c); setShowPicker(false); }}
                  >
                    <Portrait c={c} size="sm" />
                    <div>
                      <div className="oc-counselor-name">{c.name}</div>
                      <div className="oc-counselor-lbl">{c.label}</div>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Messages scroll area */}
          <div className="oc-msgs-wrap">
            <div className="oc-msgs">
              {messages.length === 0
                ? <EmptyState onSuggest={handleSend} counselor={counselor} />
                : messages.map(m => <MsgItem key={m.id} msg={m} />)
              }
              {loading && <TypingBubble counselor={counselor} />}
              <div ref={bottomRef} />
            </div>
          </div>

          {/* Pinned input bar */}
          <div className="oc-input-bar">
            <div className="oc-input-row">
              <textarea
                ref={textareaRef}
                className="oc-textarea"
                placeholder={rateLimited ? 'Daily limit reached.' : `Ask ${counselor.name}…`}
                value={input}
                onChange={e => setInput(e.target.value)}
                onKeyDown={handleKeyDown}
                disabled={loading || rateLimited}
                rows={1}
              />
              <button
                className="oc-send"
                onClick={() => handleSend()}
                disabled={!input.trim() || loading || rateLimited}
                aria-label="Send"
              >
                <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <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="oc-hint">
              {rateLimited
                ? <span>Daily limit reached · <a href="https://academy.pursuearete.com" target="_blank" rel="noopener noreferrer">Try Academy →</a></span>
                : <span className="oc-hint-desktop">{remaining} remaining today · ⏎ to send · ⇧⏎ for newline</span>
              }
              <span className="oc-hint-mobile">
                {rateLimited ? '' : `${remaining} remaining today`}
              </span>
            </div>
          </div>

        </main>
      </div>
    </div>
  );
}

// ─── Empty State ──────────────────────────────────────────────────────────────
function EmptyState({ onSuggest, counselor }) {
  return (
    <div className="oc-empty">
      <Portrait c={counselor} size="lg" />
      <h2 className="oc-empty-title">Ask anything.</h2>
      <p className="oc-empty-sub">
        The Stoic tradition has been thinking about your problems for 2,000 years.
      </p>
      <div className="oc-chips">
        {SUGGESTED.map(q => (
          <button key={q} className="oc-chip" onClick={() => onSuggest(q)}>{q}</button>
        ))}
      </div>
    </div>
  );
}

// ─── Message Items ────────────────────────────────────────────────────────────
function MsgItem({ msg }) {
  if (msg.type === 'user') {
    return (
      <div className="oc-row oc-row-user">
        <div className="oc-bubble oc-bubble-user">{msg.content}</div>
      </div>
    );
  }

  if (msg.type === 'assistant') {
    return (
      <div className="oc-row oc-row-asst">
        <div className="oc-asst-meta">
          <Portrait c={msg.counselor} size="xs" />
          <span className="oc-asst-name">{msg.counselor.name}</span>
        </div>
        <div className="oc-bubble oc-bubble-asst">{msg.content}</div>
        {msg.sources && msg.sources.length > 0 && (
          <div className="oc-sources">
            {'— '}
            {msg.sources.map((s, i) => (
              <span key={i}>{i > 0 ? ' · ' : ''}
                <em>{s.author}{s.work ? `, ${s.work}` : ''}</em>
              </span>
            ))}
          </div>
        )}
      </div>
    );
  }

  if (msg.type === 'divider') {
    return (
      <div className="oc-divider">
        <span>{msg.content}</span>
      </div>
    );
  }

  if (msg.type === 'system') {
    return (
      <div className={'oc-system' + (msg.variant === 'ratelimit' ? ' oc-sys-limit' : '') + (msg.variant === 'error' ? ' oc-sys-error' : '')}>
        <p>{msg.content}</p>
        {msg.variant === 'ratelimit' && (
          <a href="https://academy.pursuearete.com" target="_blank" rel="noopener noreferrer">
            In the meantime, begin your formation at Arete Academy →
          </a>
        )}
      </div>
    );
  }

  if (msg.type === 'cta') {
    return (
      <div className="oc-cta">
        <div className="oc-cta-title">Carry this practice with you</div>
        <div className="oc-cta-btns">
          <a href="https://apps.apple.com/app/id6762371595" target="_blank" rel="noopener noreferrer"
             className="btn-primary" style={{fontSize:13, padding:'9px 18px'}}>
            App Store
          </a>
          <a href="https://app.pursuearete.com" target="_blank" rel="noopener noreferrer"
             className="btn-ghost" style={{fontSize:13, padding:'9px 18px'}}>
            Web App
          </a>
        </div>
        <div className="oc-cta-sub">Free to start.</div>
      </div>
    );
  }

  return null;
}

// ─── Typing Indicator ─────────────────────────────────────────────────────────
function TypingBubble({ counselor }) {
  return (
    <div className="oc-row oc-row-asst">
      <div className="oc-asst-meta">
        <Portrait c={counselor} size="xs" />
        <span className="oc-asst-name">{counselor.name}</span>
      </div>
      <div className="oc-typing">
        <span/><span/><span/>
      </div>
    </div>
  );
}

// ─── Topbar ───────────────────────────────────────────────────────────────────
function OracleTopbar() {
  return (
    <header className="oc-topbar topbar-scrolled">
      <div className="topbar-inner">
        <a href="/" className="topbar-brand">
          <span className="topbar-name">ARETE</span>
        </a>
        <nav className="topbar-nav">
          <a href="/">Home</a>
          <a href="/oracle" style={{color:'var(--gold)'}}>Oracle</a>
          <a href="https://academy.pursuearete.com" target="_blank" rel="noopener noreferrer">Academy</a>
        </nav>
        <a href="https://app.pursuearete.com" target="_blank" rel="noopener noreferrer" className="topbar-cta">
          Open App
        </a>
      </div>
    </header>
  );
}
