// Reusable components for 경제 요약

const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ============ Helpers ============
function timeAgo(iso) {
  const now = new Date();
  const d = new Date(iso);
  const min = Math.floor((now - d) / 60000);
  if (min < 1) return '방금 전';
  if (min < 60) return `${min}분 전`;
  const hr = Math.floor(min / 60);
  if (hr < 24) return `${hr}시간 전`;
  const day = Math.floor(hr / 24);
  return `${day}일 전`;
}

function highlightKeywords(text, keywords, enabled) {
  if (!enabled || !keywords || !keywords.length) return text;
  const escaped = keywords.map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
  const re = new RegExp(`(${escaped.join('|')})`, 'g');
  const parts = text.split(re);
  return parts.map((p, i) => {
    if (keywords.some(k => k === p)) {
      return <span key={i} className="kw">{p}</span>;
    }
    return p;
  });
}

// ============ Stars Display ============
function StarRating({ stars, size = 14 }) {
  const filled = Math.min(5, Math.max(0, stars || 0));
  return (
    <span className="star-rating" title={`중요도 ${filled}/5`}>
      {[1, 2, 3, 4, 5].map(i => (
        <span
          key={i}
          className={`star ${i <= filled ? 'star-filled' : 'star-empty'}`}
          style={{ fontSize: size }}
        >
          ★
        </span>
      ))}
    </span>
  );
}

// ============ Star Filter Chips ============
function StarFilter({ starFilter, setStarFilter }) {
  const options = [
    { value: 0, label: '전체' },
    { value: 5, label: '★★★★★' },
    { value: 4, label: '★★★★↑' },
    { value: 3, label: '★★★↑' },
    { value: 2, label: '★★↑' },
  ];
  return (
    <div className="star-filter">
      {options.map(o => (
        <button
          key={o.value}
          className={`chip star-chip ${starFilter === o.value ? 'active' : ''}`}
          onClick={() => setStarFilter(o.value)}
        >
          {o.label}
        </button>
      ))}
    </div>
  );
}

// ============ Importance Badge ============
function ImportanceBadge({ stars }) {
  if (stars >= 5) return <span className="importance-badge importance-critical">긴급</span>;
  if (stars >= 4) return <span className="importance-badge importance-high">중요</span>;
  if (stars >= 3) return <span className="importance-badge importance-medium">주목</span>;
  return null;
}

// ============ Source Flag ============
function SourceFlag({ type }) {
  return (
    <span className={`news-source-flag ${type}`}>
      <span className="flag" aria-hidden="true"></span>
      {type === 'global' ? 'GLOBAL' : 'KOREA'}
    </span>
  );
}

// ============ Ticker Bar ============
function TickerBar({ tickers, speed }) {
  const doubled = [...tickers, ...tickers];
  return (
    <div className="ticker-bar" role="region" aria-label="실시간 시세">
      <div className="ticker-track" style={{ animationDuration: `${speed}s` }}>
        {doubled.map((t, i) => (
          <span className="ticker-item" key={i}>
            <span className="name">{t.name}</span>
            <span className="val">{t.value}</span>
            <span className={t.positive ? 'chg-up' : 'chg-dn'}>
              {t.positive ? '▲' : '▼'} {t.change.replace(/^[+-]/, '')}
            </span>
          </span>
        ))}
      </div>
    </div>
  );
}

// ============ Masthead ============
function Masthead({ theme, onToggleTheme, savedCount, onOpenSaved }) {
  const dateStr = new Date().toLocaleDateString('ko-KR', {
    year: 'numeric', month: 'long', day: 'numeric', weekday: 'long'
  });
  return (
    <header className="masthead">
      <div className="container masthead-row">
        <div className="masthead-meta">
          <span className="dot"></span>
          LIVE · {dateStr}
        </div>
        <h1 className="masthead-title">
          경제<span className="accent">.</span>요약
        </h1>
        <div className="masthead-actions">
          <button
            className={`icon-btn ${savedCount > 0 ? 'active' : ''}`}
            onClick={onOpenSaved}
            title="북마크"
            aria-label={`북마크 ${savedCount}개`}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
            </svg>
            {savedCount > 0 && <span className="badge">{savedCount}</span>}
          </button>
          <button
            className="icon-btn"
            onClick={onToggleTheme}
            title={theme === 'dark' ? '라이트 모드' : '다크 모드'}
            aria-label="테마 전환"
          >
            {theme === 'dark' ? (
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <circle cx="12" cy="12" r="4"/>
                <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>
              </svg>
            ) : (
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
              </svg>
            )}
          </button>
        </div>
      </div>
    </header>
  );
}

// ============ Sub-nav (categories + search + star filter) ============
function SubNav({ categories, activeCat, setActiveCat, query, setQuery, sourceFilter, setSourceFilter, starFilter, setStarFilter }) {
  return (
    <div className="subnav">
      <div className="container subnav-row">
        <div className="cat-chips">
          {categories.map(c => (
            <button
              key={c.id}
              className={`chip ${activeCat === c.id ? 'active' : ''}`}
              onClick={() => setActiveCat(c.id)}
            >
              {c.label}
              <span className="count">{c.count}</span>
            </button>
          ))}
        </div>
        <div className="source-toggle">
          <button className={sourceFilter === 'all' ? 'active' : ''} onClick={() => setSourceFilter('all')}>ALL</button>
          <button className={sourceFilter === 'global' ? 'active' : ''} onClick={() => setSourceFilter('global')}>해외</button>
          <button className={sourceFilter === 'korea' ? 'active' : ''} onClick={() => setSourceFilter('korea')}>한국</button>
        </div>
        <div className="search-wrap">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <circle cx="11" cy="11" r="8"/>
            <path d="m21 21-4.3-4.3"/>
          </svg>
          <input
            type="search"
            placeholder="기사 검색..."
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
        </div>
      </div>
      <div className="container" style={{ paddingTop: 10 }}>
        <StarFilter starFilter={starFilter} setStarFilter={setStarFilter} />
      </div>
    </div>
  );
}

// ============ Hero Article ============
function Hero({ article, onOpen, highlightOn, showEnglish }) {
  if (!article) return null;
  return (
    <div className="hero" onClick={() => onOpen(article)}>
      <div>
        <div className="hero-tag">
          <span className="pill">TOP STORY</span>
          <SourceFlag type={article.sourceType} />
          <span style={{ color: 'var(--muted)' }}>{article.categoryKo}</span>
          <ImportanceBadge stars={article.stars} />
        </div>
        <h2 className="hero-headline">
          {highlightKeywords(article.headline_ko, article.keywords, highlightOn)}
        </h2>
        {showEnglish && (
          <p className="hero-headline-en">{article.headline_en}</p>
        )}
        <p className="hero-summary">{article.summary_ko}</p>
        <div className="hero-meta">
          <StarRating stars={article.stars} size={13} />
          <span className="source">{article.source}</span>
          <span>·</span>
          <span>{timeAgo(article.publishedAt)}</span>
          <span>·</span>
          <span>{article.readTime}분 읽기</span>
        </div>
      </div>
      <div className="hero-side">
        <div className="ai-card">
          <div className="ai-label">
            <span className="spark"></span>
            AI 한 줄 요약
          </div>
          <p className="ai-card-text">{article.aiSummary}</p>
        </div>
      </div>
    </div>
  );
}

// ============ News Card ============
function NewsCard({ article, onOpen, isSaved, onToggleSave, highlightOn, showEnglish }) {
  return (
    <article className="news-item" onClick={() => onOpen(article)}>
      <div className="news-tag-row">
        <SourceFlag type={article.sourceType} />
        <span style={{ color: 'var(--rule-soft)' }}>·</span>
        <span className="news-cat">{article.categoryKo}</span>
        <ImportanceBadge stars={article.stars} />
        <span style={{ marginLeft: 'auto' }}>
          <StarRating stars={article.stars} size={11} />
        </span>
      </div>
      <h3 className="news-headline">
        {highlightKeywords(article.headline_ko, article.keywords, highlightOn)}
      </h3>
      {showEnglish && (
        <p className="news-headline-en">{article.headline_en}</p>
      )}
      <p className="news-summary">{article.summary_ko}</p>
      <div className="news-foot">
        <span className="src">{article.source}</span>
        <div className="right">
          <span>{timeAgo(article.publishedAt)}</span>
          <button
            className={`bookmark-btn ${isSaved ? 'saved' : ''}`}
            onClick={(e) => { e.stopPropagation(); onToggleSave(article.id); }}
            title={isSaved ? '북마크 해제' : '북마크'}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill={isSaved ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
            </svg>
          </button>
        </div>
      </div>
    </article>
  );
}

// ============ Article Modal ============
function ArticleModal({ article, onClose, isSaved, onToggleSave }) {
  const [lang, setLang] = useState('ko');

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [onClose]);

  if (!article) return null;

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div className="modal-head-meta">
            <SourceFlag type={article.sourceType} />
            <span style={{ color: 'var(--accent)' }}>{article.categoryKo}</span>
            <span style={{ color: 'var(--muted)' }}>· {article.source}</span>
            <StarRating stars={article.stars} size={13} />
            <ImportanceBadge stars={article.stars} />
          </div>
          <button className="modal-close" onClick={onClose} aria-label="닫기">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
        </div>
        <div className="modal-body">
          <h1 className="modal-headline">{article.headline_ko}</h1>
          <p className="modal-headline-alt">{article.headline_en}</p>

          <div className="modal-meta-row">
            <span className="src">{article.source}</span>
            <span>·</span>
            <span>{timeAgo(article.publishedAt)}</span>
            <span>·</span>
            <span>{article.readTime}분 읽기</span>
            <span>·</span>
            <StarRating stars={article.stars} />
            <span style={{ marginLeft: 'auto' }}>
              <button
                className={`bookmark-btn ${isSaved ? 'saved' : ''}`}
                onClick={() => onToggleSave(article.id)}
                style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, fontFamily: 'inherit' }}
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill={isSaved ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
                </svg>
                {isSaved ? '저장됨' : '북마크'}
              </button>
            </span>
          </div>

          <div className="ai-summary-block">
            <div className="label">
              <span className="spark"></span>
              AI 한 줄 요약
            </div>
            <p>{article.aiSummary}</p>
          </div>

          <div className="lang-toggle-row">
            <span className="lang-toggle-label">언어</span>
            <div className="lang-toggle">
              <button className={lang === 'ko' ? 'active' : ''} onClick={() => setLang('ko')}>한국어</button>
              <button className={lang === 'en' ? 'active' : ''} onClick={() => setLang('en')}>English</button>
              <button className={lang === 'both' ? 'active' : ''} onClick={() => setLang('both')}>나란히</button>
            </div>
          </div>

          {lang === 'ko' && (
            <p className="modal-content-text">{article.body_ko}</p>
          )}
          {lang === 'en' && (
            <p className="modal-content-text en">{article.body_en}</p>
          )}
          {lang === 'both' && (
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24 }}>
              <div>
                <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--muted)', marginBottom: 8 }}>한국어 (AI 번역)</div>
                <p className="modal-content-text" style={{ fontSize: 15 }}>{article.body_ko}</p>
              </div>
              <div>
                <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--muted)', marginBottom: 8 }}>English (Original)</div>
                <p className="modal-content-text en" style={{ fontSize: 15 }}>{article.body_en}</p>
              </div>
            </div>
          )}

          <div className="modal-keywords">
            {article.keywords.map(k => (
              <span className="kw-pill" key={k}># {k}</span>
            ))}
          </div>

          {typeof ArticleComments !== 'undefined' && (
            <ArticleComments articleId={article.id} />
          )}
        </div>
      </div>
    </div>
  );
}

// ============ Bookmarks Drawer ============
function BookmarksDrawer({ saved, articles, onOpen, onClose, onToggleSave }) {
  const items = articles.filter(a => saved.includes(a.id));
  return (
    <React.Fragment>
      <div className="drawer-backdrop" onClick={onClose}></div>
      <aside className="drawer">
        <div className="drawer-head">
          <h3>북마크 <span style={{ color: 'var(--accent)', fontStyle: 'italic', fontSize: 16, fontWeight: 400 }}>· {items.length}</span></h3>
          <button className="modal-close" onClick={onClose} aria-label="닫기">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
        </div>
        <div className="drawer-body">
          {items.length === 0 ? (
            <div className="drawer-empty">
              <div className="icon">
                <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
                </svg>
              </div>
              <div>저장된 기사가 없어요</div>
              <div style={{ fontSize: 12, marginTop: 6, color: 'var(--muted-2)' }}>관심있는 기사의 북마크 아이콘을 눌러보세요</div>
            </div>
          ) : items.map(a => (
            <div className="drawer-item" key={a.id} onClick={() => onOpen(a)}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
                <h4>{a.headline_ko}</h4>
                <button
                  className="bookmark-btn saved"
                  onClick={(e) => { e.stopPropagation(); onToggleSave(a.id); }}
                  title="북마크 해제"
                  style={{ flexShrink: 0 }}
                >
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth="2">
                    <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
                  </svg>
                </button>
              </div>
              <div className="meta">
                <StarRating stars={a.stars} size={10} />
                {' '}{a.source} · {a.categoryKo} · {timeAgo(a.publishedAt)}
              </div>
            </div>
          ))}
        </div>
      </aside>
    </React.Fragment>
  );
}

// ============ Footer ============
function Footer() {
  return (
    <footer>
      <div className="container foot-row">
        <div>
          <div className="brand">경제<span className="accent">.</span>요약</div>
          <div style={{ marginTop: 4 }}>해외·한국 경제 뉴스 · AI 한국어 번역 · 자동 업데이트 · 로그인 불필요</div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="mono" style={{ fontSize: 11 }}>★ 중요도 분류 · 5=긴급 · 4=중요 · 3=주목 · 2=참고 · 1=일반</div>
          <div style={{ marginTop: 4, fontSize: 11 }}>Bloomberg · Reuters · FT · WSJ · 매일경제 · 한국경제 · 조선비즈</div>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  TickerBar, Masthead, SubNav, Hero, NewsCard,
  ArticleModal, BookmarksDrawer, Footer,
  StarRating, StarFilter, ImportanceBadge,
  timeAgo, highlightKeywords
});
