// ─── Wave 23-C — GaokaoFaqBlock (FAQ 升级 + 搜索) ─────────────────────────────
// Extends Wave 3 FAQ MVP with:
//   1. 25+ Q&A pairs covering common HI gaokao concerns
//   2. Client-side search box — substring match across q+a, both zh/en
//   3. <mark> keyword highlighting in results
//   4. "No match" fallback prompting a 1-on-1 consult
//
// Pure client-side, NO LLM, NO external API.
//
// Also exports window.PBFaqMatcher = { matchFaq } for unit testing.

// ─── Matcher helper ──────────────────────────────────────────────────────────
;(function () {
  /**
   * matchFaq(query, allFaqs) → filtered array of FAQ items that match query.
   * Matching rules:
   *   - Empty / whitespace-only query → return all items unchanged.
   *   - Otherwise: lowercase, substring match in q OR a text.
   *   - Each returned item gets a `_query` field (the normalised query string)
   *     so the renderer can highlight without re-computing.
   *
   * @param {string} query
   * @param {Array<{q:string, a:string}>} allFaqs
   * @returns {Array<{q:string, a:string, _query?:string}>}
   */
  function matchFaq(query, allFaqs) {
    if (!query || !query.trim()) return allFaqs;
    const q = query.trim().toLowerCase();
    return allFaqs.filter(function (item) {
      return (
        (item.q && item.q.toLowerCase().includes(q)) ||
        (item.a && item.a.toLowerCase().includes(q))
      );
    }).map(function (item) {
      return Object.assign({}, item, { _query: q });
    });
  }

  window.PBFaqMatcher = { matchFaq: matchFaq };
})();

// ─── Highlight helper (React) ─────────────────────────────────────────────────
function highlightText(text, query) {
  if (!query || !text) return text;
  const lc = text.toLowerCase();
  const lcq = query.toLowerCase();
  const idx = lc.indexOf(lcq);
  if (idx === -1) return text;
  return React.createElement(
    React.Fragment,
    null,
    text.slice(0, idx),
    React.createElement('mark', {
      style: { background: 'rgba(255, 200, 40, 0.45)', borderRadius: 2, padding: '0 1px' },
    }, text.slice(idx, idx + query.length)),
    highlightText(text.slice(idx + query.length), query),
  );
}

// ─── Component ────────────────────────────────────────────────────────────────
const GaokaoFaqBlock = ({ lang }) => {
  const [open, setOpen] = React.useState(false);
  const [openIdx, setOpenIdx] = React.useState(0);
  const [searchQuery, setSearchQuery] = React.useState('');

  const fallbackZh = (window.I18N && window.I18N.zh && window.I18N.zh.gk && window.I18N.zh.gk.faq) || null;
  const dict = (window.I18N && window.I18N[lang] && window.I18N[lang].gk && window.I18N[lang].gk.faq) || fallbackZh || {
    chip: 'FAQ',
    title: 'FAQ',
    subtitle: '',
    close: 'Close',
    items: [],
    search: { placeholder: '搜索问题或关键词', empty: '未找到匹配的问答，建议预约 30 分钟一对一顾问咨询' },
  };

  const allItems = Array.isArray(dict.items) ? dict.items : [];
  const searchDict = dict.search || {};
  const searchPlaceholder = searchDict.placeholder || (lang === 'en' ? 'Search questions or keywords' : '搜索问题或关键词');
  const searchEmpty = searchDict.empty || (lang === 'en'
    ? 'No matching Q&A found. Consider booking a free 30-min 1-on-1 consultant session.'
    : '未找到匹配的问答，建议预约 30 分钟一对一顾问咨询');

  const filteredItems = window.PBFaqMatcher
    ? window.PBFaqMatcher.matchFaq(searchQuery, allItems)
    : allItems;

  // Reset expanded item when search changes
  React.useEffect(() => {
    setOpenIdx(0);
  }, [searchQuery]);

  // Lock body scroll while modal is open
  React.useEffect(() => {
    if (typeof document === 'undefined' || !document.body) return;
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [open]);

  // Close on ESC
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    const onHash = () => setOpen(false); // #323(1) — close on route change
    window.addEventListener('keydown', onKey);
    window.addEventListener('hashchange', onHash);
    return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('hashchange', onHash); };
  }, [open]);

  // Reset search when modal closes
  const handleClose = () => {
    setOpen(false);
    setSearchQuery('');
    setOpenIdx(0);
  };

  return (
    <React.Fragment>
      {/* ── FAQ chip — always rendered ── */}
      <button
        type="button"
        data-testid="gaokao-faq-chip"
        onClick={() => setOpen(true)}
        style={{
          display: 'inline-flex',
          alignItems: 'center',
          gap: 6,
          padding: '6px 14px',
          fontSize: 12,
          fontWeight: 600,
          letterSpacing: '0.04em',
          textTransform: 'uppercase',
          borderRadius: 100,
          border: '1px solid var(--pb-gold-500)',
          background: 'transparent',
          color: 'var(--pb-gold-700)',
          cursor: 'pointer',
          transition: 'background 0.15s, color 0.15s',
        }}
        onMouseEnter={(e) => {
          e.currentTarget.style.background = 'var(--pb-gold-500)';
          e.currentTarget.style.color = 'var(--pb-navy-900)';
        }}
        onMouseLeave={(e) => {
          e.currentTarget.style.background = 'transparent';
          e.currentTarget.style.color = 'var(--pb-gold-700)';
        }}
      >
        <span aria-hidden="true" style={{ fontSize: 14, lineHeight: 1 }}>?</span>
        {dict.chip || 'FAQ'}
      </button>

      {/* ── Modal — portalled to body to escape sticky stacking context (#258) ── */}
      {open && ReactDOM.createPortal(
        <div
          data-testid="gaokao-faq-modal"
          role="dialog"
          aria-modal="true"
          aria-labelledby="gaokao-faq-modal-title"
          style={{
            position: 'fixed',
            inset: 0,
            zIndex: 2147483647,
            background: 'rgba(15, 22, 36, 0.55)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: '96px 24px 24px',
          }}
          onClick={(e) => { if (e.target === e.currentTarget) handleClose(); }}
        >
          <div
            className="pb-card"
            style={{
              maxWidth: 720,
              width: '100%',
              maxHeight: 'calc(100vh - 128px)',
              overflow: 'auto',
              padding: 0,
              boxShadow: '0 20px 60px rgba(0,0,0,0.35)',
            }}
          >
            {/* Header */}
            <div
              style={{
                padding: '24px 28px 16px',
                borderBottom: '1px solid var(--pb-border)',
                display: 'flex',
                flexDirection: 'column',
                gap: 12,
                position: 'sticky',
                top: 0,
                background: 'var(--pb-paper)',
                zIndex: 1,
              }}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
                <div>
                  <div className="pb-eyebrow" style={{ color: 'var(--pb-gold-700)', marginBottom: 8 }}>
                    {dict.eyebrow || (lang === 'zh' ? '常见问题 · FAQ' : 'Common questions · FAQ')}
                  </div>
                  <h3
                    id="gaokao-faq-modal-title"
                    style={{ fontFamily: 'var(--pb-serif)', fontSize: 22, fontWeight: 600, margin: 0 }}
                  >
                    {dict.title || (lang === 'zh' ? '高考志愿测算 · 常见问题' : 'Gaokao planner · FAQ')}
                  </h3>
                  {dict.subtitle && (
                    <p style={{ fontSize: 13, color: 'var(--pb-fg-muted)', margin: '6px 0 0', lineHeight: 1.6 }}>
                      {dict.subtitle}
                    </p>
                  )}
                </div>
                <button
                  type="button"
                  data-testid="gaokao-faq-close"
                  aria-label={dict.close || (lang === 'zh' ? '关闭' : 'Close')}
                  onClick={handleClose}
                  style={{
                    background: 'transparent',
                    border: '1px solid var(--pb-border)',
                    borderRadius: 18,
                    fontSize: 16,
                    height: 36,
                    lineHeight: 1,
                    padding: 0,
                    cursor: 'pointer',
                    color: 'var(--pb-fg-muted)',
                    display: 'inline-flex',
                    alignItems: 'center',
                    flexShrink: 0,
                    justifyContent: 'center',
                    width: 36,
                  }}
                >
                  ×
                </button>
              </div>

              {/* Search box */}
              <div style={{ position: 'relative' }}>
                <span
                  aria-hidden="true"
                  style={{
                    position: 'absolute',
                    left: 12,
                    top: '50%',
                    transform: 'translateY(-50%)',
                    fontSize: 14,
                    color: 'var(--pb-fg-muted)',
                    pointerEvents: 'none',
                  }}
                >
                  🔍
                </span>
                <input
                  type="search"
                  data-testid="gaokao-faq-search"
                  placeholder={searchPlaceholder}
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  aria-label={searchPlaceholder}
                  style={{
                    width: '100%',
                    boxSizing: 'border-box',
                    padding: '9px 12px 9px 36px',
                    fontSize: 13,
                    border: '1px solid var(--pb-border)',
                    borderRadius: 8,
                    background: 'var(--pb-surface-alt)',
                    color: 'var(--pb-fg)',
                    outline: 'none',
                    fontFamily: 'inherit',
                  }}
                />
                {searchQuery && (
                  <button
                    type="button"
                    aria-label="clear search"
                    onClick={() => setSearchQuery('')}
                    style={{
                      position: 'absolute',
                      right: 10,
                      top: '50%',
                      transform: 'translateY(-50%)',
                      background: 'transparent',
                      border: 'none',
                      cursor: 'pointer',
                      fontSize: 13,
                      color: 'var(--pb-fg-muted)',
                      padding: '2px 4px',
                    }}
                  >
                    ×
                  </button>
                )}
              </div>
            </div>

            {/* Q&A list */}
            <div style={{ padding: '8px 0' }}>
              {filteredItems.length === 0 && (
                <div
                  data-testid="gaokao-faq-empty"
                  style={{ padding: '32px 28px', textAlign: 'center', color: 'var(--pb-fg-muted)', fontSize: 13, lineHeight: 1.7 }}
                >
                  {searchEmpty}
                </div>
              )}
              {filteredItems.map((qa, idx) => {
                const isOpen = openIdx === idx;
                const query = qa._query || '';
                return (
                  <div
                    key={idx}
                    data-testid={`faq-question-${idx}`}
                    style={{ borderTop: idx === 0 ? 'none' : '1px solid var(--pb-border)' }}
                  >
                    <button
                      type="button"
                      data-testid={`faq-question-toggle-${idx}`}
                      onClick={() => setOpenIdx(isOpen ? -1 : idx)}
                      aria-expanded={isOpen}
                      style={{
                        width: '100%',
                        textAlign: 'left',
                        background: 'transparent',
                        border: 'none',
                        padding: '16px 28px',
                        cursor: 'pointer',
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        gap: 16,
                      }}
                    >
                      <span
                        style={{
                          fontFamily: 'var(--pb-serif)',
                          fontSize: 15,
                          fontWeight: 600,
                          color: 'var(--pb-fg)',
                          lineHeight: 1.45,
                        }}
                      >
                        {query ? highlightText(qa.q, query) : qa.q}
                      </span>
                      <span
                        aria-hidden="true"
                        style={{
                          fontSize: 16,
                          color: 'var(--pb-fg-muted)',
                          transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
                          transition: 'transform 0.15s',
                          flexShrink: 0,
                        }}
                      >
                        ▾
                      </span>
                    </button>
                    {isOpen && (
                      <div
                        data-testid={`faq-answer-${idx}`}
                        style={{
                          padding: '0 28px 18px',
                          fontSize: 13,
                          color: 'var(--pb-fg)',
                          lineHeight: 1.7,
                          whiteSpace: 'pre-line',
                        }}
                      >
                        {query ? highlightText(qa.a, query) : qa.a}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>

            {/* Footer note */}
            <div
              style={{
                padding: '14px 28px',
                borderTop: '1px solid var(--pb-border)',
                background: 'var(--pb-surface-alt)',
                fontSize: 11,
                color: 'var(--pb-fg-muted)',
                lineHeight: 1.6,
              }}
            >
              {dict.footer || (lang === 'zh'
                ? '没找到答案？可以预约 30 分钟一对一顾问咨询。'
                : 'Did not find what you need? Book a free 30-min planner consult.')}
            </div>
          </div>
        </div>
      , document.body)}
    </React.Fragment>
  );
};

window.GaokaoFaqBlock = GaokaoFaqBlock;
