/* =========================================================
   三藏閣 — 백과 (Encyclopedia)
   - 인덱스: 카테고리별 항목 그리드 + 검색
   - 상세: 한국어/한문/원어 표제, 검수 상태, 절·관련 항목·출처
   ========================================================= */

const { Icon: EIcon } = window;

const ENCY_TYPES = {
  concept:  '개념',
  person:   '인물',
  text:     '문헌',
  school:   '종파',
  place:    '지명',
  practice: '수행',
  ritual:   '의례',
  icon:     '도상',
  history:  '역사',
};

const ENCY_MAIN_TABS = [
  {
    id: 'concepts',
    name: '불교 개념 사전',
    sub: '교리·인물·문헌·종파·역사',
  },
  {
    id: 'practice',
    name: '수행 백과',
    sub: '수행어·방법·전통·지도',
  },
];

const PRACTICE_TAGS = [
  { id: 'all', name: '전체' },
  { id: 'foundation', name: '기초 수행어' },
  { id: 'calm-insight', name: '집중·통찰' },
  { id: 'path', name: '길·단계' },
  { id: 'traditions', name: '전통별 수행' },
  { id: 'guidance', name: '지도·안전' },
];

const PRACTICE_TAXONOMY = [
  {
    id: 'foundation',
    title: '수행의 기초',
    desc: '수행을 무엇이라 부르고, 마음을 어떻게 기억하고 돌보는지 정리합니다.',
    topics: [
      {
        title: '수행을 부르는 말',
        items: [
          { entryId: 'bhavana' },
          { label: '수습과 닦음', roman: 'bhāvanā', status: '준비 중' },
          { label: '업처', roman: 'kammaṭṭhāna', status: '준비 중' },
        ],
      },
      {
        title: '주의와 기억',
        items: [
          { entryId: 'sati' },
          { label: '분명한 앎', roman: 'sampajañña', status: '준비 중' },
          { label: '정념', roman: 'sammā-sati', status: '준비 중' },
        ],
      },
    ],
  },
  {
    id: 'calm-insight',
    title: '집중과 통찰',
    desc: '고요함, 삼매, 통찰을 따로 보되 실제 수행에서 만나는 관계도 함께 봅니다.',
    topics: [
      {
        title: '고요함과 몰입',
        items: [
          { entryId: 'samatha' },
          { entryId: 'samadhi' },
          { label: '선정', roman: 'jhāna / dhyāna', status: '준비 중' },
        ],
      },
      {
        title: '통찰과 관찰',
        items: [
          { entryId: 'vipassana' },
          { label: '사념처', roman: 'satipaṭṭhāna', status: '준비 중' },
          { label: '몸·느낌·마음·법', roman: 'kāya · vedanā · citta · dhamma', status: '준비 중' },
        ],
      },
    ],
  },
  {
    id: 'path',
    title: '길과 단계',
    desc: '수행자가 실제로 묻는 길, 지표, 장애, 성취의 언어를 단계적으로 엮습니다.',
    topics: [
      {
        title: '길의 구조',
        items: [
          { label: '팔정도', roman: 'ariya aṭṭhaṅgika magga', status: '준비 중' },
          { label: '칠각지', roman: 'bojjhaṅga', status: '준비 중' },
          { label: '오근·오력', roman: 'indriya · bala', status: '준비 중' },
        ],
      },
      {
        title: '장애와 점검',
        items: [
          { label: '오개', roman: 'nīvaraṇa', status: '준비 중' },
          { label: '선정의 지표', roman: 'jhāna factors', status: '준비 중' },
          { label: '통찰의 지표', roman: 'insight knowledges', status: '준비 중' },
        ],
      },
    ],
  },
  {
    id: 'traditions',
    title: '전통별 수행 체계',
    desc: '한국불교, 남방불교, 티벳불교의 수행 언어를 서로 비교할 수 있게 정리합니다.',
    topics: [
      {
        title: '한국불교와 선',
        items: [
          { label: '간화선', roman: 'ganhwa seon', status: '준비 중' },
          { label: '염불선', roman: 'yeombul seon', status: '준비 중' },
          { label: '참회와 발원', roman: 'repentance · aspiration', status: '준비 중' },
        ],
      },
      {
        title: '남방불교 수행',
        items: [
          { label: '마하시 전통', roman: 'Mahāsi', status: '준비 중' },
          { label: '고엔카 전통', roman: 'Goenka', status: '준비 중' },
          { label: '아잔 차 숲 전통', roman: 'Thai forest', status: '준비 중' },
        ],
      },
      {
        title: '티벳불교 수행',
        items: [
          { label: '람림', roman: 'lam rim', status: '준비 중' },
          { label: '로종', roman: 'blo sbyong', status: '준비 중' },
          { label: '족첸·마하무드라', roman: 'rdzogs chen · mahāmudrā', status: '준비 중' },
        ],
      },
    ],
  },
  {
    id: 'guidance',
    title: '지도와 안전',
    desc: '명상지도사가 현장에서 확인해야 할 설명 방식, 한계, 안전 기준을 다룹니다.',
    topics: [
      {
        title: '지도 언어',
        items: [
          { label: '초심자 안내', roman: 'beginner guidance', status: '준비 중' },
          { label: '면담과 점검', roman: 'interview', status: '준비 중' },
          { label: '수행 일지', roman: 'practice log', status: '준비 중' },
        ],
      },
      {
        title: '주의가 필요한 경우',
        items: [
          { label: '강한 체험의 해석', roman: 'meditative experience', status: '준비 중' },
          { label: '심리적 어려움', roman: 'practice safety', status: '준비 중' },
          { label: '전문가 연계', roman: 'referral', status: '준비 중' },
        ],
      },
    ],
  },
];

const countPracticeItems = (groups) => groups.reduce((sum, group) => (
  sum + group.topics.reduce((topicSum, topic) => topicSum + topic.items.length, 0)
), 0);

const getPracticeEntryIds = (groups) => {
  const ids = new Set();
  groups.forEach(group => {
    group.topics.forEach(topic => {
      topic.items.forEach(item => {
        if (item.entryId) ids.add(item.entryId);
      });
    });
  });
  return ids;
};

/* ---------- 라우터 어댑터: app.jsx 가 부르는 진입점 ---------- */
window.Encyclopedia = ({ entryId, catId, onOpenEntry, onOpenPassage, onOpenDict, onRoute }) => {
  const [openId, setOpenId] = React.useState(entryId || null);
  React.useEffect(() => { setOpenId(entryId || null); }, [entryId]);
  if (openId) {
    return <window.EncyclopediaDetail
      entryId={openId}
      onOpenEntry={(id) => { setOpenId(id); onOpenEntry && onOpenEntry(id); }}
      onBack={() => { setOpenId(null); onRoute && onRoute({ name: 'encyclopedia' }); }}
      onOpenDict={onOpenDict}
    />;
  }
  return <window.EncyclopediaIndex
    onOpenEntry={(id) => { setOpenId(id); onOpenEntry && onOpenEntry(id); }}
    initialCat={catId}
    onRoute={onRoute}
  />;
};

/* ---------- 인덱스 ---------- */
window.EncyclopediaIndex = ({ onOpenEntry, initialCat, onRoute }) => {
  const [q, setQ] = React.useState('');
  const [activeMain, setActiveMain] = React.useState(initialCat === 'practice' ? 'practice' : 'concepts');
  const [activeCat, setActiveCat] = React.useState(initialCat && initialCat !== 'practice' ? initialCat : 'all');
  const [activePracticeTag, setActivePracticeTag] = React.useState('all');
  React.useEffect(() => {
    if (!initialCat) return;
    setActiveMain(initialCat === 'practice' ? 'practice' : 'concepts');
    setActiveCat(initialCat === 'practice' ? 'all' : initialCat);
    setActivePracticeTag('all');
  }, [initialCat]);

  const entries = Object.values(window.ENCY_ENTRIES).filter(e => !e.hidden);
  const conceptCollections = window.ENCY_COLLECTIONS.filter(c => c.id !== 'practice');
  const conceptEntries = entries.filter(e => e.type !== 'practice');
  const practiceEntries = entries.filter(e => e.type === 'practice');
  const scopedEntries = activeMain === 'practice' ? practiceEntries : conceptEntries;
  const activeCollections = activeMain === 'practice'
    ? window.ENCY_COLLECTIONS.filter(c => c.id === 'practice')
    : conceptCollections;
  const activePracticeGroups = activePracticeTag === 'all'
    ? PRACTICE_TAXONOMY
    : PRACTICE_TAXONOMY.filter(group => group.id === activePracticeTag);
  const activePracticeEntryIds = getPracticeEntryIds(activePracticeGroups);

  const matchesQuery = (e) => {
    if (!q.trim()) return true;
    const hay = [e.head.kr, e.head.han, e.head.skt, e.head.pi, e.head.tib, e.head.en, e.oneline]
      .filter(Boolean).join(' ').toLowerCase();
    return hay.includes(q.toLowerCase());
  };
  const filtered = scopedEntries.filter(e => {
    if (activeCat !== 'all' && e.type !== activeCat) return false;
    if (activeMain === 'practice' && !q.trim() && activePracticeTag !== 'all' && !activePracticeEntryIds.has(e.id)) return false;
    return matchesQuery(e);
  });
  const searchPlaceholder = activeMain === 'practice'
    ? '수행 항목 검색…  예) 사띠, 사마타, 위빠사나, 삼매'
    : '불교 개념 검색…  예) 공성, 연기, 용수, 반야심경';

  const switchMain = (id) => {
    setActiveMain(id);
    setActiveCat('all');
    setActivePracticeTag('all');
    setQ('');
  };

  const renderPracticeItem = (item) => {
    const entry = item.entryId ? window.ENCY_ENTRIES[item.entryId] : null;
    if (entry) {
      return (
        <button key={entry.id} className="ency__practice-item" onClick={() => onOpenEntry(entry.id)}>
          <span className="ency__practice-item-name">{entry.head.kr}</span>
          <span className="ency__practice-item-meta">{entry.head.pi || entry.head.skt || entry.head.en}</span>
          <span className="ency__practice-item-status">공개</span>
        </button>
      );
    }
    return (
      <div key={item.label} className="ency__practice-item is-planned">
        <span className="ency__practice-item-name">{item.label}</span>
        <span className="ency__practice-item-meta">{item.roman}</span>
        <span className="ency__practice-item-status">{item.status}</span>
      </div>
    );
  };

  const renderCard = (e) => {
    const cat = window.ENCY_COLLECTIONS.find(c => c.id === e.type);
    return (
      <button key={e.id} className="ency-card" onClick={() => onOpenEntry(e.id)} style={{'--c': cat?.c || '#666'}}>
        <div className="ency-card__type">
          <span className="ency-card__type-name">{cat?.name}</span>
        </div>
        <div className="ency-card__title">
          <span className="ency-card__title-kr">{e.head.kr}</span>
          <span className="ency-card__title-han">{e.head.han}</span>
        </div>
        <div className="ency-card__skt">{e.head.skt || e.head.pi || e.head.tib}</div>
        <div className="ency-card__one">{e.oneline}</div>
        <div className={'ency-card__status ency-card__status--' + e.statusKey}>
          <span className="ency-card__status-dot" />
          {e.status}
        </div>
      </button>
    );
  };

  return (
    <div className="ency" data-screen-label="02 백과">

      <header className="ency__hero">
        <div className="ency__hero-inner">
          <div className="ency__hero-eyebrow">백과 · ENCYCLOPEDIA</div>
          <h1 className="ency__hero-title">백과</h1>
          <p className="ency__hero-sub">불교 개념 사전과 수행 백과를 나누어 찾아봅니다.</p>

          <div className="ency__search">
            <EIcon name="search" size={18}/>
            <input
              data-screen-search
              placeholder={searchPlaceholder}
              value={q}
              onChange={e => setQ(e.target.value)}
            />
            {q && <button className="ency__search-clear" onClick={() => setQ('')}><EIcon name="close" size={16}/></button>}
          </div>
        </div>
      </header>

      <div className="ency__inner">

        <div className="ency__main-tabs" role="tablist" aria-label="백과 영역">
          {ENCY_MAIN_TABS.map(tab => (
            <button
              key={tab.id}
              role="tab"
              aria-selected={activeMain === tab.id}
              className={'ency__main-tab' + (activeMain === tab.id ? ' is-active' : '')}
              onClick={() => switchMain(tab.id)}
            >
              <span className="ency__main-tab-name">{tab.name}</span>
              <span className="ency__main-tab-sub">{tab.sub}</span>
            </button>
          ))}
        </div>

        {activeMain === 'concepts' && (
          <React.Fragment>
            <div className="ency__section-head">
              <div>
                <div className="ency__section-eyebrow">불교 개념 사전 · TERMS</div>
                <h2 className="ency__section-title">불교 개념 사전</h2>
              </div>
              <span className="ency__section-count">{filtered.length} 항목</span>
            </div>

            <div className="ency__cats">
              <button
                className={'ency__cat' + (activeCat==='all' ? ' is-active' : '')}
                onClick={() => setActiveCat('all')}
              >
                <span className="ency__cat-name">전체</span>
                <span className="ency__cat-count">{conceptEntries.length}</span>
              </button>
              {activeCollections.map(c => (
                <button
                  key={c.id}
                  className={'ency__cat' + (activeCat===c.id ? ' is-active' : '')}
                  style={{'--c': c.c}}
                  onClick={() => setActiveCat(c.id)}
                >
                  <span className="ency__cat-name">{c.name}</span>
                  <span className="ency__cat-count">{c.count}</span>
                </button>
              ))}
            </div>
          </React.Fragment>
        )}

        {activeMain === 'practice' && !q.trim() && (
          <section className="ency__practice" aria-label="수행 백과 목차">
            <div className="ency__section-head">
              <div>
                <div className="ency__section-eyebrow">수행 백과 · PRACTICE</div>
                <h2 className="ency__section-title">수행 백과</h2>
              </div>
              <span className="ency__section-count">{practiceEntries.length} 항목 공개</span>
            </div>

            <div className="ency__cats ency__cats--practice">
              {PRACTICE_TAGS.map(tag => {
                const groups = tag.id === 'all'
                  ? PRACTICE_TAXONOMY
                  : PRACTICE_TAXONOMY.filter(group => group.id === tag.id);
                return (
                  <button
                    key={tag.id}
                    className={'ency__cat' + (activePracticeTag === tag.id ? ' is-active' : '')}
                    onClick={() => setActivePracticeTag(tag.id)}
                  >
                    <span className="ency__cat-name">{tag.name}</span>
                    <span className="ency__cat-count">{countPracticeItems(groups)}</span>
                  </button>
                );
              })}
            </div>

            <div className="ency__practice-taxonomy">
              {activePracticeGroups.map(group => (
                <section key={group.id} className="ency__practice-domain">
                  <div className="ency__practice-domain-head">
                    <span>대주제</span>
                    <h3>{group.title}</h3>
                    <p>{group.desc}</p>
                  </div>
                  <div className="ency__practice-topic-list">
                    {group.topics.map(topic => (
                      <div key={topic.title} className="ency__practice-topic">
                        <h4>{topic.title}</h4>
                        <div className="ency__practice-items">
                          {topic.items.map(renderPracticeItem)}
                        </div>
                      </div>
                    ))}
                  </div>
                </section>
              ))}
            </div>
          </section>
        )}

        {activeMain === 'practice' && q.trim() && (
          <div className="ency__section-head">
            <div>
              <div className="ency__section-eyebrow">수행 백과 · SEARCH</div>
              <h2 className="ency__section-title">수행 항목 검색</h2>
            </div>
            <span className="ency__section-count">{filtered.length} 항목</span>
          </div>
        )}

        {/* 결과 */}
        <div className="ency__results">
          <div className="ency__results-head">
            <span>{filtered.length} 항목</span>
            <span className="ency__results-sub">{activeMain === 'practice' ? '수행 백과 항목' : '불교 개념 사전 항목'}</span>
          </div>
          <div className="ency__grid">
            {filtered.map(renderCard)}
            {filtered.length === 0 && (
              <div className="ency__empty">
                <EIcon name="search" size={32}/>
                <span>{activeMain === 'practice' && !q.trim() ? '이 분류의 공개 항목은 준비 중입니다.' : '일치하는 항목이 없습니다.'}</span>
                <span className="ency__empty-sub">검수 진행 중인 항목은 곧 추가됩니다.</span>
              </div>
            )}
          </div>
        </div>

        {activeMain === 'concepts' && (
          <section className="ency__map">
            <div className="ency__map-head">
              <h2 className="ency__map-title">핵심 개념 지도</h2>
              <a className="ency__map-link" onClick={() => onRoute ? onRoute({name:'explore'}) : window.dispatchEvent(new CustomEvent('app-route', {detail:{name:'explore'}}))}>탐구 탭에서 보기 →</a>
            </div>
            <window.ConceptMapPreview onOpenEntry={onOpenEntry}/>
          </section>
        )}

      </div>
    </div>
  );
};

/* ---------- 핵심 개념 지도 (백과 안 작은 미리보기) ---------- */
window.ConceptMapPreview = ({ onOpenEntry }) => {
  const seed = window.GRAPH_SEED;
  const W = 880, H = 280;
  const proj = (x, y) => ({ cx: x * W, cy: y * H * 0.9 + 20 });
  return (
    <div className="ency-map">
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet" className="ency-map__svg">
        {seed.edges.map(([a,b], i) => {
          const A = seed.nodes.find(n => n.id===a);
          const B = seed.nodes.find(n => n.id===b);
          const pa = proj(A.x, A.y), pb = proj(B.x, B.y);
          return <line key={i} x1={pa.cx} y1={pa.cy} x2={pb.cx} y2={pb.cy} stroke="rgba(60,40,20,.18)" strokeWidth="0.8"/>;
        })}
        {seed.nodes.map(n => {
          const p = proj(n.x, n.y);
          const c = n.kind==='concept' ? '#5a3820' : n.kind==='person' ? '#2a3f5f' : n.kind==='school' ? '#2e5c4a' : '#6b2c5a';
          return (
            <g key={n.id} className="ency-map__node" onClick={() => onOpenEntry(n.id)}>
              <circle cx={p.cx} cy={p.cy} r={n.w/2.4} fill="rgba(250,246,236,0.9)" stroke={c} strokeWidth="1"/>
              <text x={p.cx} y={p.cy+4} textAnchor="middle" fontSize="13" fill={c} fontWeight="500">{n.label}</text>
            </g>
          );
        })}
      </svg>
    </div>
  );
};

/* ---------- 항목 상세 ---------- */
const STATUS_TO_VKEY = {
  'verified': 'verified',
  'pending':  'review',
  'draft':    'draft',
  'stable':   'stable',
};

window.EncyclopediaDetail = ({ entryId, onOpenEntry, onBack, onOpenDict }) => {
  const e = window.ENCY_ENTRIES[entryId];
  if (!e) {
    return <div style={{padding:60, textAlign:'center', color:'var(--ink-mute)'}}>항목을 찾을 수 없습니다.</div>;
  }
  const cat = window.ENCY_COLLECTIONS.find(c => c.id === e.type);

  /* kg-ref 클릭 가로채기 */
  const onBodyClick = (ev) => {
    const a = ev.target.closest && ev.target.closest('.kg-ref');
    if (!a) return;
    ev.preventDefault();
    onOpenEntry(a.dataset.id);
  };

  /* 학술 메타 — 데이터에 없으면 합리적 기본값 */
  const meta = {
    created:   e.created   || '2026.01',
    updated:   e.updated   || '2026.05',
    editor:    e.editor    || '편집위원',
    revisions: e.revisions || 3,
    status:    STATUS_TO_VKEY[e.statusKey] || 'review',
  };
  const license = e.license || { preset: 'self' };

  return (
    <div className="ency-detail" data-screen-label="02b 백과 항목">
      <div className="ency-detail__inner">
        <button className="ency-detail__back" onClick={onBack}>
          <EIcon name="arrow-left" size={16}/>
          <span>백과로</span>
        </button>

        <header className="ency-detail__head">
          <div className="ency-detail__crumb">
            <span>{cat?.name}</span>
          </div>
          <h1 className="ency-detail__title">
            <span className="ency-detail__title-kr">{e.head.kr}</span>
            <span className="ency-detail__title-han">{e.head.han}</span>
          </h1>
          {(e.head.skt || e.head.pi || e.head.tib || e.head.en) && (
            <div className="ency-detail__title-romans">
              {e.head.skt && <span><i>SKT</i><b>{e.head.skt}</b></span>}
              {e.head.pi  && <span><i>PĀLI</i><b>{e.head.pi}</b></span>}
              {e.head.en  && <span><i>EN</i><b>{e.head.en}</b></span>}
            </div>
          )}
        </header>

        {/* 짧은 정의 — 항목 상단 고정 */}
        <window.DefinitionBox>{e.oneline}</window.DefinitionBox>

        {/* 다국어 명칭법 */}
        <window.MultilingualBox names={{
          kr:  e.head.kr,
          han: e.head.han,
          pi:  e.head.pi,
          skt: e.head.skt,
          tib: e.head.tib,
          en:  e.head.en,
        }}/>

        {/* 버전 / 검수 */}
        <window.VersionBlock
          created={meta.created}
          updated={meta.updated}
          status={meta.status}
          editor={meta.editor}
          revisions={meta.revisions}
        />

        <div className="ency-detail__grid">
          {/* 본문 */}
          <article className="ency-detail__body" onClick={onBodyClick}>
            {e.sections.map(s => (
              <section key={s.id} className="ency-detail__section" id={s.id}>
                <h2 className="ency-detail__section-title">{s.title}</h2>
                <div className="ency-detail__section-body" dangerouslySetInnerHTML={{__html: s.body}}/>
              </section>
            ))}

            {/* 라이선스 & 인용 — 본문 말미 */}
            <section className="ency-detail__section ency-detail__section--legal">
              <h2 className="ency-detail__section-title">출처 · 인용 · 라이선스</h2>
              <window.LicenseBadge {...license}/>
              <div className="ency-detail__actions">
                <window.CitationButton entry={{
                  author: '삼장각 편집부',
                  title: e.head.kr + (e.head.han ? ` · ${e.head.han}` : ''),
                  year: 2026,
                  updated: meta.updated,
                  id: e.id,
                }}/>
                {onOpenDict && (
                  <button className="sch-cite-btn" onClick={() => onOpenDict(e.id + '-d')}>
                    <EIcon name="translate" size={14}/>
                    <span>사전에서 보기</span>
                  </button>
                )}
              </div>
            </section>

            {/* 메모 — 로컬 저장 */}
            <window.NotePanel k={'ency:' + e.id}/>
          </article>

          {/* 사이드 */}
          <aside className="ency-detail__side">
            <section className="ency-detail__side-block">
              <h3 className="ency-detail__side-title">목차</h3>
              <ul className="ency-detail__toc">
                {e.sections.map(s => <li key={s.id}><a href={`#${s.id}`}>{s.title}</a></li>)}
                <li><a href="#legal">출처 · 인용 · 라이선스</a></li>
              </ul>
            </section>

            {e.related && e.related.length > 0 && (
              <section className="ency-detail__side-block">
                <h3 className="ency-detail__side-title">관련 항목</h3>
                <div className="ency-detail__related">
                  {e.related.map(r => (
                    <button key={r.id} className="ency-detail__related-item" onClick={() => onOpenEntry(r.id)}>
                      <span className="han">{r.han}</span>
                      <span>{r.name}</span>
                    </button>
                  ))}
                </div>
              </section>
            )}

            {e.sources && e.sources.length > 0 && (
              <section className="ency-detail__side-block">
                <h3 className="ency-detail__side-title">근거 · 출전</h3>
                <ul className="ency-detail__sources">
                  {e.sources.map((s, i) => (
                    <li key={i}>
                      <span>{s.label}</span>
                      <span className="ency-detail__sources-detail">{s.detail}</span>
                    </li>
                  ))}
                </ul>
              </section>
            )}

            {/* 개념 관계도 — 유료/로드맵 미리보기 */}
            <section className="ency-detail__side-block ency-detail__side-block--locked">
              <h3 className="ency-detail__side-title">
                개념 관계도
                <span className="ency-detail__side-tag">준비 중</span>
              </h3>
              <p className="ency-detail__locked-note">
                이 항목을 중심으로 한 개념 관계도는 색인 탭에서 준비 중입니다.
              </p>
            </section>
          </aside>
        </div>
      </div>
    </div>
  );
};
