import React, { useState, useEffect, useCallback } from 'react';
import { getEpisodes, deleteEpisode } from '../api/orchestration';
import ReactMarkdown from 'react-markdown';

const PAGE_SIZE = 20;

export default function MemoryView({ onNavigate, onBack }) {
  const [episodes, setEpisodes]   = useState([]);
  const [total, setTotal]         = useState(0);
  const [offset, setOffset]       = useState(0);
  const [search, setSearch]       = useState('');
  const [query, setQuery]         = useState('');   // committed search term
  const [expanded, setExpanded]   = useState(null); // episode id
  const [loading, setLoading]     = useState(false);
  const [error, setError]         = useState(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await getEpisodes({ limit: PAGE_SIZE, offset, q: query || undefined });
      setEpisodes(data.episodes);
      setTotal(data.total);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [offset, query]);

  useEffect(() => { load(); }, [load]);

  function handleSearch(e) {
    e.preventDefault();
    setOffset(0);       // reset to page 1 on new search
    setQuery(search);
  }

  async function handleDelete(id) {
    if (!confirm('Delete this memory? This cannot be undone.')) return;
    await deleteEpisode(id);
    load();
  }

  

  const totalPages = Math.ceil(total / PAGE_SIZE);
  const currentPage = Math.floor(offset / PAGE_SIZE) + 1;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', flex: 1, overflow: 'hidden', background: 'var(--bg-base)' }}>

      {/* Header */}
      <div className="panel-header" style={{ padding: '0 24px', gap: 12 }}>
        <button className="btn-icon" onClick={onBack} title="Back">
          ←
        </button>
        <span className="text-base" style={{ fontWeight: 500 }}>Memory Viewer</span>
        <span className="text-sm text-muted" style={{ marginLeft: 'auto' }}>
          {total} episode{total !== 1 ? 's' : ''}
        </span>
      </div>

      {/* Search bar */}
      <form onSubmit={handleSearch} style={{ padding: '12px 24px', borderBottom: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', gap: 8 }}>
          <input
            className="text-sm"
            value={search}
            onChange={e => setSearch(e.target.value)}
            placeholder="Search memories…"
            style={{
              flex: 1, padding: '8px 12px',
              background: 'var(--bg-surface)', border: '1px solid var(--border)',
              borderRadius: 'var(--radius)', color: 'var(--text-primary)',
            }}
          />
          <button type="submit" className="btn-primary" style={{ padding: '8px 16px' }}>
            Search
          </button>
          {query && (
            <button type="button" className="btn-icon" onClick={() => { setSearch(''); setQuery(''); setOffset(0); }}>
              ✕
            </button>
          )}
        </div>
      </form>

      {/* Episode list */}
      <div className="scroll-y flex-1" style={{ padding: '16px 24px' }}>
        {loading && <p className="text-sm text-muted">Loading…</p>}
        {error  && <p className="text-sm" style={{ color: 'var(--error, #e05)' }}>{error}</p>}
        {!loading && episodes.length === 0 && (
          <p className="text-sm text-muted">No memories found.</p>
        )}

        {episodes.map(ep => (
          <EpisodeCard
            key={ep.id}
            episode={ep}
            expanded={expanded === ep.id}
            onToggle={() => setExpanded(expanded === ep.id ? null : ep.id)}
            onDelete={() => handleDelete(ep.id)}
          />
        ))}
      </div>

      {/* Pagination */}
      {totalPages > 1 && (
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          gap: 12, padding: '12px', borderTop: '1px solid var(--border)',
        }}>
          <button className="btn-icon" disabled={offset === 0}
            onClick={() => setOffset(o => Math.max(0, o - PAGE_SIZE))}>←</button>
          <span className="text-sm text-muted">{currentPage} / {totalPages}</span>
          <button className="btn-icon" disabled={currentPage >= totalPages}
            onClick={() => setOffset(o => o + PAGE_SIZE)}>→</button>
        </div>
      )}
    </div>
  );
}

function stripMarkdown(text) {
  return text
    .replace(/\*\*(.*?)\*\*/g, '$1')  // bold
    .replace(/\*(.*?)\*/g, '$1')       // italic
    .replace(/`([^`]+)`/g, '$1')       // inline code
    .replace(/^#{1,6}\s+/gm, '')       // headings
    .replace(/^\s*[-*+]\s+/gm, '')     // list markers
    .trim();
}

function EpisodeCard({ episode, expanded, onToggle, onDelete }) {
  const date = new Date(episode.created_at * 1000).toLocaleString();
  const preview = stripMarkdown(episode.user_message).slice(0, 80) + 
  (episode.user_message.length > 80 ? '…' : '');

  return (
    <div style={{
      background: 'var(--bg-surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', marginBottom: 8, overflow: 'hidden',
    }}>
      {/* Card header — always visible */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 14px', cursor: 'pointer' }}
        onClick={onToggle}>
        <span style={{ flex: 1, fontSize: 13, color: 'var(--text-primary)' }}>{preview}</span>
        <span className="text-sm text-muted">{date}</span>
        <span className="text-muted" style={{ fontSize: 11 }}>#{episode.id}</span>
        <button className="btn-icon" style={{ color: 'var(--error, #e05)', fontSize: 14 }}
          onClick={e => { e.stopPropagation(); onDelete(); }} title="Delete">🗑</button>
        <span className="text-muted" style={{ fontSize: 11 }}>{expanded ? '▲' : '▼'}</span>
      </div>

      {/* Expanded content */}
      {expanded && (
        <div style={{ padding: '0 14px 14px', borderTop: '1px solid var(--border)' }}>
          <MessageBlock label="You" content={episode.user_message} color="var(--accent)" />
          <MessageBlock label="NexusAI" content={episode.ai_response} color="var(--text-secondary)" />
          {episode.token_count > 0 && (
            <p className="text-sm text-muted" style={{ marginTop: 8 }}>
              Tokens: {episode.token_count}
            </p>
          )}
        </div>
      )}
    </div>
  );
}

function MessageBlock({ label, content, color }) {
  const isAI = label === 'NexusAI';
  return (
    <div style={{ marginTop: 12 }}>
      <p style={{ fontSize: 11, fontWeight: 600, color, marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.05em' }}>
        {label}
      </p>
        <ReactMarkdown
            components={{
              p:      ({children}) => <p style={{ margin: '0 0 8px', lineHeight: 1.6, fontSize: 13 }}>{children}</p>,
              ul:     ({children}) => <ul style={{ margin: '0 0 8px', paddingLeft: '20px' }}>{children}</ul>,
              ol:     ({children}) => <ol style={{ margin: '0 0 8px', paddingLeft: '20px' }}>{children}</ol>,
              li:     ({children}) => <li style={{ marginBottom: '2px', fontSize: 13 }}>{children}</li>,
              code:   ({inline, children}) => inline
                ? <code style={{ background: 'var(--bg-elevated)', padding: '1px 5px', borderRadius: 'var(--radius-sm)', fontSize: 12, fontFamily: 'monospace' }}>{children}</code>
                : <pre style={{ background: 'var(--bg-elevated)', padding: '10px 12px', borderRadius: 'var(--radius-md)', overflowX: 'auto', fontSize: 12, fontFamily: 'monospace' }}><code>{children}</code></pre>,
              strong: ({children}) => <strong style={{ fontWeight: 600, color: 'var(--text-primary)' }}>{children}</strong>,
            }}
          >{content}</ReactMarkdown>

    </div>
  );
}