'use client';

export const runtime = 'edge';

// Mira Wiki 單篇頁
// SDD: polaris/mira/.agents/specs/mira-app/design.md §5.2 + §3.5.12
// 對應 task: 7C.2 + 7B.3g
// 路由：/mira/wiki/[pageName]
// 顯示：wiki-page parent → wiki-paragraph children (按 facet 分區) → triplet grandchildren
// 7B.3g 升級：樹狀渲染 + 折疊 + triplet 跨 wiki 連結化

import { useEffect, useMemo, useState, use } from 'react';
import Link from 'next/link';
import { MarkdownView } from '../../_shared/markdown';
import '../../mira.css';

const KBDB_BASE = 'https://kbdb.finally.click';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';

type Block = {
  id: string;
  page_name: string | null;
  content: string;
  type: string;
  parent_id: string | null;
  tags_json: string | null;
  source: string | null;
  created_at: number;
  updated_at: number;
};

type FacetGroup = {
  facet: string;
  paragraphs: Array<{
    block: Block;
    triplets: Block[];
  }>;
};

export default function WikiPagePage({
  params,
}: {
  params: Promise<{ pageName: string }>;
}) {
  const { pageName } = use(params);
  const decodedName = decodeURIComponent(pageName);

  const [block, setBlock] = useState<Block | null>(null);
  const [paragraphs, setParagraphs] = useState<Block[]>([]);
  const [triplets, setTriplets] = useState<Block[]>([]);
  const [entitySet, setEntitySet] = useState<Set<string>>(new Set());
  const [collapsed, setCollapsed] = useState<Record<string, boolean>>({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const meRes = await fetch(`${API_BASE}/me`, { credentials: 'include' });
        if (!meRes.ok) throw new Error('未登入');
        const me = (await meRes.json()) as { api_key: string };
        const headers = { Authorization: `Bearer ${me.api_key}` };

        // 1. 抓 wiki-page parent block by page_name
        const pageRes = await fetch(
          `${KBDB_BASE}/blocks?page_name=${encodeURIComponent(decodedName)}&limit=1`,
          { headers },
        );
        if (!pageRes.ok) throw new Error(`KBDB ${pageRes.status}`);
        const pageData = await pageRes.json();
        const wikiPage: Block | undefined = pageData.blocks?.[0];
        if (cancelled) return;
        if (!wikiPage) {
          setError(`找不到 wiki page：${decodedName}`);
          return;
        }
        setBlock(wikiPage);

        // 2. 平行撈所有 wiki-paragraph + triplet + wiki-page（跨 wiki 連結用），客戶端 filter by parent_id
        //    KBDB 沒 parent_id server filter（兼 tag filter 還有 KI-3 bug），用 source+type 取再 client-side filter
        const [paraRes, tripRes, pageListRes] = await Promise.all([
          fetch(`${KBDB_BASE}/blocks?source=ai-canon-wiki&type=wiki-paragraph&limit=500`, { headers }),
          fetch(`${KBDB_BASE}/blocks?source=ai-canon-wiki&type=triplet&limit=1000`, { headers }),
          fetch(`${KBDB_BASE}/blocks?source=ai-canon-wiki&type=wiki-page&limit=500`, { headers }),
        ]);
        if (!paraRes.ok || !tripRes.ok || !pageListRes.ok) {
          throw new Error('KBDB tree fetch failed');
        }
        const paraData = await paraRes.json();
        const tripData = await tripRes.json();
        const pageListData = await pageListRes.json();
        if (cancelled) return;

        const allParas: Block[] = paraData.blocks ?? [];
        const allTrips: Block[] = tripData.blocks ?? [];
        const allPages: Block[] = pageListData.blocks ?? [];

        // 該 wiki-page 的 paragraphs
        const myParas = allParas
          .filter((p) => p.parent_id === wikiPage.id)
          .sort((a, b) => a.created_at - b.created_at);
        setParagraphs(myParas);

        // 該 wiki-page 範圍內所有 paragraph 的 triplets
        const paraIdSet = new Set(myParas.map((p) => p.id));
        const myTrips = allTrips.filter((t) => t.parent_id && paraIdSet.has(t.parent_id));
        setTriplets(myTrips);

        // 跨 wiki 連結用：所有 wiki-page 的 entity 名稱（content 就是 entity）
        // 額外把 page_name 也加入（page_name=wiki-{entity}）
        const eset = new Set<string>();
        for (const p of allPages) {
          if (p.content) eset.add(p.content.trim());
          if (p.page_name?.startsWith('wiki-')) {
            eset.add(p.page_name.slice(5).trim());
          }
        }
        setEntitySet(eset);
      } catch (e: any) {
        if (!cancelled) setError(e?.message ?? 'load failed');
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    load();
    return () => {
      cancelled = true;
    };
  }, [decodedName]);

  // 按 facet 分區
  const facetGroups = useMemo<FacetGroup[]>(() => {
    const groups: Map<string, Array<{ block: Block; triplets: Block[] }>> = new Map();
    for (const p of paragraphs) {
      const facet = extractFacet(p.tags_json) ?? '未分類';
      const myTrips = triplets.filter((t) => t.parent_id === p.id);
      if (!groups.has(facet)) groups.set(facet, []);
      groups.get(facet)!.push({ block: p, triplets: myTrips });
    }
    return Array.from(groups.entries()).map(([facet, paragraphs]) => ({ facet, paragraphs }));
  }, [paragraphs, triplets]);

  const entity = block?.content?.trim() || decodedName.replace(/^wiki-/, '');
  const isWikiPage = block?.type === 'wiki-page';

  function toggleCollapse(key: string) {
    setCollapsed((c) => ({ ...c, [key]: !c[key] }));
  }

  return (
    <main className="mira-app">
      <div className="mira-content mira-wiki-detail">
        <header style={{ padding: '24px 0 16px', borderBottom: '1px solid #2a2a2a' }}>
          <Link
            href="/mira/wiki"
            style={{ color: '#888', fontSize: 14, textDecoration: 'none' }}
          >
            ← Wiki 索引
          </Link>
          <h1 style={{ fontSize: 28, fontWeight: 700, color: '#fff', margin: '8px 0 4px' }}>
            {entity}
          </h1>
          {block && (
            <div style={{ color: '#666', fontSize: 12 }}>
              {block.type} ・ updated {new Date(block.updated_at * 1000).toLocaleString('zh-TW')}
            </div>
          )}
        </header>

        {loading && <div style={{ padding: 24, color: '#666' }}>載入中⋯</div>}
        {error && <div style={{ padding: 24, color: '#e66' }}>{error}</div>}

        {block && !loading && !error && (
          <>
            {/* wiki-page tree view */}
            {isWikiPage && facetGroups.length > 0 && (
              <article style={{ padding: '8px 0 24px' }}>
                {facetGroups.map((group) => (
                  <FacetSection
                    key={group.facet}
                    group={group}
                    entitySet={entitySet}
                    collapsed={collapsed}
                    toggleCollapse={toggleCollapse}
                  />
                ))}
              </article>
            )}

            {/* wiki-page 但沒 children：fallback render content */}
            {isWikiPage && facetGroups.length === 0 && (
              <article style={{ padding: '8px 0 24px', color: '#888' }}>
                <em>尚無段落（wiki_synthesis 還沒跑出 children）</em>
                <MarkdownView text={block.content} />
              </article>
            )}

            {/* 非 wiki-page（schema / index / log / index-entry 等）：直接 render content */}
            {!isWikiPage && (
              <article style={{ padding: '20px 0' }}>
                <MarkdownView text={block.content} />
              </article>
            )}

            <footer
              style={{
                padding: '20px 0',
                borderTop: '1px solid #1f1f1f',
                color: '#555',
                fontSize: 12,
              }}
            >
              <div>id: <span style={{ fontFamily: 'monospace' }}>{block.id}</span></div>
              <div>type: {block.type}</div>
              {block.source && <div>source: {block.source}</div>}
              {block.parent_id && (
                <div>
                  parent: <span style={{ fontFamily: 'monospace' }}>{block.parent_id}</span>
                </div>
              )}
              {paragraphs.length > 0 && (
                <div>
                  {paragraphs.length} paragraph(s) ・ {triplets.length} triplet(s)
                </div>
              )}
            </footer>
          </>
        )}
      </div>
    </main>
  );
}

function FacetSection({
  group,
  entitySet,
  collapsed,
  toggleCollapse,
}: {
  group: FacetGroup;
  entitySet: Set<string>;
  collapsed: Record<string, boolean>;
  toggleCollapse: (key: string) => void;
}) {
  const key = `facet:${group.facet}`;
  const isCollapsed = collapsed[key] ?? false; // 預設展開（leo 看一篇 wiki 時要看內容）

  return (
    <section style={{ margin: '16px 0', borderLeft: '3px solid #2a3a4a', paddingLeft: 14 }}>
      <button
        onClick={() => toggleCollapse(key)}
        style={{
          background: 'transparent',
          border: 'none',
          color: '#aab',
          fontSize: 16,
          fontWeight: 600,
          padding: '4px 0',
          cursor: 'pointer',
          textAlign: 'left',
          width: '100%',
        }}
      >
        {isCollapsed ? '▸' : '▾'} {group.facet}
        <span style={{ color: '#555', fontWeight: 400, fontSize: 13, marginLeft: 8 }}>
          ({group.paragraphs.length})
        </span>
      </button>
      {!isCollapsed &&
        group.paragraphs.map((p) => (
          <ParagraphBlock
            key={p.block.id}
            block={p.block}
            triplets={p.triplets}
            entitySet={entitySet}
            collapsed={collapsed}
            toggleCollapse={toggleCollapse}
          />
        ))}
    </section>
  );
}

function ParagraphBlock({
  block,
  triplets,
  entitySet,
  collapsed,
  toggleCollapse,
}: {
  block: Block;
  triplets: Block[];
  entitySet: Set<string>;
  collapsed: Record<string, boolean>;
  toggleCollapse: (key: string) => void;
}) {
  const tripKey = `trip:${block.id}`;
  const tripsCollapsed = collapsed[tripKey] ?? true; // triplets 預設折疊

  return (
    <div style={{ margin: '12px 0 16px', paddingLeft: 4 }}>
      <div style={{ color: '#ddd', lineHeight: 1.7 }}>
        <MarkdownView text={block.content} />
      </div>
      {triplets.length > 0 && (
        <div style={{ marginTop: 8 }}>
          <button
            onClick={() => toggleCollapse(tripKey)}
            style={{
              background: 'transparent',
              border: 'none',
              color: '#666',
              fontSize: 12,
              padding: '2px 0',
              cursor: 'pointer',
            }}
          >
            {tripsCollapsed ? '▸' : '▾'} 關係 ({triplets.length})
          </button>
          {!tripsCollapsed && (
            <ul style={{ listStyle: 'none', padding: '4px 0 0 12px', margin: 0 }}>
              {triplets.map((t) => (
                <li
                  key={t.id}
                  style={{
                    color: '#888',
                    fontSize: 13,
                    padding: '2px 0',
                    fontFamily: 'monospace',
                  }}
                >
                  <TripletRender content={t.content} entitySet={entitySet} />
                </li>
              ))}
            </ul>
          )}
        </div>
      )}
    </div>
  );
}

/** Render triplet "A >> 關係 >> B" with A/B linkified if they match an existing wiki entity */
function TripletRender({
  content,
  entitySet,
}: {
  content: string;
  entitySet: Set<string>;
}) {
  // 切「>>」分 A / 關係 / B
  const parts = content.split('>>').map((s) => s.trim());
  if (parts.length !== 3) {
    return <>{content}</>;
  }
  const [a, rel, b] = parts;
  return (
    <>
      <EntityLink name={a} entitySet={entitySet} />{' '}
      <span style={{ color: '#666' }}>&gt;&gt; {rel} &gt;&gt;</span>{' '}
      <EntityLink name={b} entitySet={entitySet} />
    </>
  );
}

function EntityLink({ name, entitySet }: { name: string; entitySet: Set<string> }) {
  if (entitySet.has(name)) {
    return (
      <Link
        href={`/mira/wiki/${encodeURIComponent(`wiki-${name}`)}`}
        style={{ color: '#88c0ff', textDecoration: 'none' }}
      >
        {name}
      </Link>
    );
  }
  return <span style={{ color: '#ccc' }}>{name}</span>;
}

function extractFacet(tags_json: string | null | undefined): string | null {
  if (!tags_json) return null;
  try {
    const tags = JSON.parse(tags_json) as string[];
    const facetTag = tags.find((t) => t.startsWith('facet:'));
    return facetTag ? facetTag.slice(6) : null;
  } catch {
    return null;
  }
}
