// Knowledge Map — visualizes collections and bookmarks as a clustered graph

function KnowledgeMap() {
  const [hover, setHover] = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const [viewMode, setViewMode] = React.useState('work'); // 'work' or 'personal'

  // Force-directed-style layout (manually positioned for determinism)
  // 7 collections, with bookmarks clustered around each
  const W = 920, H = 560;

  const workClusters = [
    { id: "ai",       name: "AI & ML",        cx: 280, cy: 200, color: "#2563EB", r: 105 },
    { id: "design",   name: "Design Systems", cx: 600, cy: 170, color: "#A855F7", r: 90 },
    { id: "startups", name: "Startups",       cx: 760, cy: 360, color: "#10B981", r: 78 },
    { id: "tools",    name: "Dev Tools",      cx: 480, cy: 420, color: "#F59E0B", r: 80 },
    { id: "essays",   name: "Long Reads",     cx: 200, cy: 430, color: "#EF4444", r: 72 },
    { id: "research", name: "Research",       cx: 420, cy: 100, color: "#06B6D4", r: 68 },
  ];

  const personalClusters = [
    { id: "travel",     name: "Travel",           cx: 250, cy: 180, color: "#2563EB", r: 95,  icon: "✈" },
    { id: "cooking",    name: "Cooking",           cx: 500, cy: 160, color: "#EF4444", r: 88,  icon: "🍳" },
    { id: "food",       name: "Food Influencers", cx: 720, cy: 200, color: "#F97316", r: 80,  icon: "🍕" },
    { id: "buylater",   name: "Buy Later",        cx: 680, cy: 400, color: "#8B5CF6", r: 82,  icon: "🛒" },
    { id: "sale",       name: "Sale",             cx: 350, cy: 420, color: "#10B981", r: 72,  icon: "🏷" },
    { id: "fashion",    name: "Fashion",          cx: 160, cy: 380, color: "#EC4899", r: 78,  icon: "👗" },
  ];

  const personalNodes = [
    { id:'p1', title:'Best Cafés in Lisbon', collection:'travel', tags:['lisbon','food'], domain:'travelblog.com', thumbColor:'#2563EB', thumb:'LB' },
    { id:'p2', title:'Japan Itinerary 2 Weeks', collection:'travel', tags:['japan','planning'], domain:'nomadicmatt.com', thumbColor:'#2563EB', thumb:'JP' },
    { id:'p3', title:'Hidden Gems Amalfi Coast', collection:'travel', tags:['italy','beach'], domain:'lonelyplanet.com', thumbColor:'#2563EB', thumb:'AM' },
    { id:'p4', title:'Sourdough Bread Recipe', collection:'cooking', tags:['baking','bread'], domain:'kingarthur.com', thumbColor:'#EF4444', thumb:'SD' },
    { id:'p5', title:'One-Pot Pasta Tricks', collection:'cooking', tags:['pasta','easy'], domain:'seriouseats.com', thumbColor:'#EF4444', thumb:'PT' },
    { id:'p6', title:'Homemade Ramen Guide', collection:'cooking', tags:['ramen','japanese'], domain:'youtube.com', thumbColor:'#EF4444', thumb:'RM' },
    { id:'p7', title:'Best Street Food NYC', collection:'food', tags:['nyc','streetfood'], domain:'eater.com', thumbColor:'#F97316', thumb:'SF' },
    { id:'p8', title:'Top 10 Food TikTokers', collection:'food', tags:['tiktok','reviews'], domain:'buzzfeed.com', thumbColor:'#F97316', thumb:'TT' },
    { id:'p9', title:'Sony WH-1000XM6 Review', collection:'buylater', tags:['headphones','audio'], domain:'wirecutter.com', thumbColor:'#8B5CF6', thumb:'SN' },
    { id:'p10', title:'Standing Desk Comparison', collection:'buylater', tags:['desk','wfh'], domain:'rtings.com', thumbColor:'#8B5CF6', thumb:'DK' },
    { id:'p11', title:'Kindle Paperwhite 2026', collection:'buylater', tags:['kindle','reading'], domain:'amazon.com', thumbColor:'#8B5CF6', thumb:'KP' },
    { id:'p12', title:'End of Season Nike Sale', collection:'sale', tags:['nike','shoes'], domain:'nike.com', thumbColor:'#10B981', thumb:'NK' },
    { id:'p13', title:'Uniqlo Summer Drop', collection:'sale', tags:['uniqlo','summer'], domain:'uniqlo.com', thumbColor:'#10B981', thumb:'UQ' },
    { id:'p14', title:'Spring 2026 Trends', collection:'fashion', tags:['trends','spring'], domain:'vogue.com', thumbColor:'#EC4899', thumb:'SP' },
    { id:'p15', title:'Capsule Wardrobe Guide', collection:'fashion', tags:['capsule','minimal'], domain:'pinterest.com', thumbColor:'#EC4899', thumb:'CW' },
    { id:'p16', title:'Sneaker Release Calendar', collection:'fashion', tags:['sneakers','drops'], domain:'hypebeast.com', thumbColor:'#EC4899', thumb:'SR' },
  ];

  const clusters = viewMode === 'work' ? workClusters : personalClusters;

  // Position each bookmark inside its cluster
  const sourceBookmarks = viewMode === 'work' ? SAMPLE.bookmarks : personalNodes;
  const nodes = sourceBookmarks.map((b, i) => {
    const c = clusters.find(c => c.id === b.collection);
    if (!c) return null;
    const clusterItems = sourceBookmarks.filter(x => x.collection === b.collection);
    const idxInCluster = clusterItems.indexOf(b);
    const totalInCluster = clusterItems.length;
    const angle = (idxInCluster / totalInCluster) * Math.PI * 2 + (b.id.charCodeAt(1) % 7) * 0.18;
    const dist = c.r * (0.55 + ((b.id.charCodeAt(1) * 7) % 100) / 240);
    return {
      ...b,
      x: c.cx + Math.cos(angle) * dist,
      y: c.cy + Math.sin(angle) * dist,
      cluster: c,
    };
  }).filter(Boolean);

  // Edges between bookmarks that share tags
  const edges = [];
  for (let i = 0; i < nodes.length; i++) {
    for (let j = i + 1; j < nodes.length; j++) {
      const a = nodes[i], b = nodes[j];
      const shared = a.tags.filter(t => b.tags.includes(t)).length;
      if (shared >= 1 && a.cluster.id !== b.cluster.id) {
        edges.push({ a, b, w: shared });
      }
    }
  }
  // Cluster-internal edges (lighter, structural)
  clusters.forEach(c => {
    const cn = nodes.filter(n => n.cluster.id === c.id);
    cn.forEach(n => edges.push({ a: { x: c.cx, y: c.cy, isCenter: true, cluster: c }, b: n, w: 0, internal: true }));
  });

  const selectedNode = selected ? nodes.find(n => n.id === selected) : null;

  return (
    <div className="main-inner wide">
      <div className="page-head">
        <div>
          <h1 className="page-title">Insights</h1>
          <p className="page-subtitle">A visual overview of your collections and how they connect. Click a node to expand.</p>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost btn-sm"><I.Sparkle className="icon icon-sm" /> Re-cluster with AI</button>
          <button className="btn btn-ghost btn-sm"><I.Filter className="icon icon-sm" /> Filter</button>
          <button className="btn btn-ghost btn-sm"><I.Download className="icon icon-sm" /> Export</button>
        </div>
      </div>

      <div className="card km-canvas" style={{padding:0, overflow:'hidden', position:'relative'}}>
        {/* Toolbar */}
        <div className="km-toolbar" style={{position:'absolute', top:14, left:14, display:'flex', gap:6, zIndex:5}}>
          <div style={{background:'var(--surface)', border:'0.5px solid var(--border)', borderRadius:10, padding:'4px 10px', fontSize:11, color:'var(--text-3)', display:'inline-flex', alignItems:'center', gap:6}}>
            <span style={{width:6, height:6, borderRadius:'50%', background:'var(--blue)'}}></span>
            {viewMode === 'work' ? '172 bookmarks · 6 clusters · 47 connections' : '16 bookmarks · 6 categories'}
          </div>
          {/* Work / Personal toggle */}
          <div style={{background:'var(--surface)', border:'0.5px solid var(--border)', borderRadius:10, padding:'2px', fontSize:11, display:'inline-flex', gap:0}}>
            <button
              onClick={() => { setViewMode('work'); setSelected(null); setHover(null); }}
              style={{
                padding:'3px 12px', borderRadius:8, border:'none', cursor:'pointer',
                background: viewMode === 'work' ? 'var(--blue)' : 'transparent',
                color: viewMode === 'work' ? '#fff' : 'var(--text-3)',
                fontWeight: 600, fontSize:11, fontFamily:'inherit', transition:'all 150ms ease',
              }}
            >Work</button>
            <button
              onClick={() => { setViewMode('personal'); setSelected(null); setHover(null); }}
              style={{
                padding:'3px 12px', borderRadius:8, border:'none', cursor:'pointer',
                background: viewMode === 'personal' ? 'var(--blue)' : 'transparent',
                color: viewMode === 'personal' ? '#fff' : 'var(--text-3)',
                fontWeight: 600, fontSize:11, fontFamily:'inherit', transition:'all 150ms ease',
              }}
            >Personal</button>
          </div>
        </div>
        <div className="km-zoom" style={{position:'absolute', top:14, right:14, display:'flex', gap:4, zIndex:5}}>
          <button className="btn-icon" style={{background:'var(--surface)', border:'0.5px solid var(--border)'}}><I.Plus className="icon icon-sm" /></button>
          <button className="btn-icon" style={{background:'var(--surface)', border:'0.5px solid var(--border)'}}><I.ArrowDown className="icon icon-sm" /></button>
          <button className="btn-icon tooltip-host" data-tip="Reset view" style={{background:'var(--surface)', border:'0.5px solid var(--border)'}}><I.Map className="icon icon-sm" /></button>
        </div>

        <svg className="km-svg" viewBox={`0 0 ${W} ${H}`} style={{display:'block', width:'100%', height:560, background:'var(--surface)'}}>
          {/* Grid backdrop */}
          <defs>
            <pattern id="kmgrid" width="40" height="40" patternUnits="userSpaceOnUse">
              <circle cx="1" cy="1" r="0.7" fill="var(--border)" />
            </pattern>
            <radialGradient id="cluster-fade" cx="0.5" cy="0.5" r="0.5">
              <stop offset="0%" stopOpacity="0.18" />
              <stop offset="100%" stopOpacity="0.02" />
            </radialGradient>
          </defs>
          <rect x="0" y="0" width={W} height={H} fill="url(#kmgrid)" />

          {/* Cluster halos */}
          {clusters.map(c => (
            <circle key={c.id+'-halo'} cx={c.cx} cy={c.cy} r={c.r + 18} fill={c.color} opacity={viewMode === 'personal' ? 0.1 : 0.06} />
          ))}

          {/* Edges */}
          {edges.map((e, i) => (
            <line
              key={i}
              x1={e.a.x} y1={e.a.y} x2={e.b.x} y2={e.b.y}
              stroke={e.internal ? (e.b.cluster.color) : "var(--text-4)"}
              strokeWidth={e.internal ? 0.8 : Math.min(2, 0.6 + e.w * 0.7)}
              opacity={e.internal ? 0.25 : (hover && (hover === e.a.id || hover === e.b.id) ? 0.7 : 0.18)}
              strokeDasharray={e.internal ? "0" : "3 3"}
            />
          ))}

          {/* Cluster centers */}
          {clusters.map(c => (
            <g key={c.id}>
              <circle cx={c.cx} cy={c.cy} r={11} fill={c.color} />
              <circle cx={c.cx} cy={c.cy} r={11} fill="none" stroke={c.color} strokeWidth="2" opacity="0.3" style={{transformOrigin:`${c.cx}px ${c.cy}px`}}>
                <animate attributeName="r" values="11;18;11" dur="3s" repeatCount="indefinite" />
                <animate attributeName="opacity" values="0.3;0;0.3" dur="3s" repeatCount="indefinite" />
              </circle>
              {viewMode === 'personal' && c.icon && (
                <text x={c.cx} y={c.cy + 5} textAnchor="middle" fontSize="12" fill="#fff" style={{pointerEvents:'none'}}>{c.icon}</text>
              )}
              <text x={c.cx} y={c.cy - 22} textAnchor="middle" fontSize="11" fontWeight="700" fill="var(--text-1)" style={{fontFamily:'DM Sans', letterSpacing:'-0.01em'}}>{c.name}</text>
              <text x={c.cx} y={c.cy - 8} textAnchor="middle" fontSize="9" fontWeight="600" fill="var(--text-4)" style={{fontFamily:'DM Mono', letterSpacing:'0.04em'}}>{c.id.toUpperCase()} · {sourceBookmarks.filter(b => b.collection === c.id).length}</text>
            </g>
          ))}

          {/* Bookmark nodes */}
          {nodes.map(n => {
            const isHover = hover === n.id;
            const isSel = selected === n.id;
            return (
              <g key={n.id} style={{cursor:'pointer'}}
                onMouseEnter={() => setHover(n.id)}
                onMouseLeave={() => setHover(null)}
                onClick={() => setSelected(selected === n.id ? null : n.id)}
              >
                <circle cx={n.x} cy={n.y} r={isSel ? 8 : (isHover ? 7 : 5)} fill={n.cluster.color} fillOpacity={isHover || isSel ? 1 : 0.85} stroke="var(--surface)" strokeWidth="1.5" style={{transition:'all 120ms ease-out'}}/>
                {(isHover || isSel) && (
                  <g>
                    <rect x={n.x + 10} y={n.y - 14} width={Math.min(n.title.length * 5.5 + 14, 240)} height="22" rx="6" fill="var(--text-1)" />
                    <text x={n.x + 17} y={n.y + 1} fontSize="10" fontWeight="600" fill="var(--bg)" style={{fontFamily:'DM Sans'}}>
                      {n.title.length > 38 ? n.title.slice(0, 38) + '…' : n.title}
                    </text>
                  </g>
                )}
              </g>
            );
          })}
        </svg>

        {/* Legend */}
        <div className="km-legend" style={{position:'absolute', bottom:14, left:14, background:'var(--surface)', border:'0.5px solid var(--border)', borderRadius:10, padding:'10px 14px', display:'flex', flexDirection:'column', gap:6, fontSize:10}}>
          <div style={{fontSize:10, fontWeight:700, color:'var(--text-4)', letterSpacing:'0.08em', textTransform:'uppercase', marginBottom:2}}>Legend</div>
          <div style={{display:'flex', alignItems:'center', gap:6, color:'var(--text-3)'}}>
            <svg width="20" height="6"><line x1="0" y1="3" x2="20" y2="3" stroke="var(--text-4)" strokeWidth="1.5" strokeDasharray="3 3" /></svg>
            Shared tag
          </div>
          <div style={{display:'flex', alignItems:'center', gap:6, color:'var(--text-3)'}}>
            <svg width="20" height="6"><line x1="0" y1="3" x2="20" y2="3" stroke="var(--blue)" strokeWidth="1" /></svg>
            In collection
          </div>
        </div>

        {/* Detail panel for selected */}
        {selectedNode && (
          <div className="fade-in km-detail" style={{position:'absolute', bottom:14, right:14, width:300, background:'var(--surface)', border:'0.5px solid var(--border)', borderRadius:12, padding:14, boxShadow:'var(--shadow-md)'}}>
            <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:8, marginBottom:8}}>
              <span className="collection-chip"><I.Folder /> {selectedNode.cluster.name}</span>
              <button className="btn-icon" onClick={() => setSelected(null)}><I.Close className="icon icon-sm" /></button>
            </div>
            <div style={{fontSize:13, fontWeight:600, color:'var(--text-1)', marginBottom:6, letterSpacing:'-0.01em'}}>{selectedNode.title}</div>
            <div style={{fontSize:11, color:'var(--text-4)', marginBottom:10}}>{selectedNode.domain}</div>
            <div style={{display:'flex', flexWrap:'wrap', gap:4, marginBottom:12}}>
              {selectedNode.tags.map(t => <span key={t} className="tag">#{t}</span>)}
            </div>
            <button className="btn btn-primary btn-sm" style={{width:'100%'}}><I.External className="icon icon-sm" /> Open bookmark</button>
          </div>
        )}
      </div>

      {/* AI insights panel */}
      <div className="km-insights-grid" style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:10, marginTop:20}}>
        {(viewMode === 'work' ? [
          { icon: I.Sparkle, label: "Emerging cluster", title: "Inference cost & latency", body: "5 new bookmarks tagged #inference, #latency in the last 2 weeks. Worth its own collection?" },
          { icon: I.Brain, label: "Strongest connection", title: "AI ↔ Design", body: "12 bookmarks bridge these clusters. Common thread: AI app UX patterns." },
          { icon: I.Eye, label: "Forgotten reading", title: "Research backlog", body: "9 bookmarks in Research haven't been opened in 30+ days. Skim or archive?" },
        ] : [
          { icon: I.Sparkle, label: "Trending interest", title: "Japan trip planning", body: "You've saved 4 travel articles about Japan this week. Create a dedicated trip folder?" },
          { icon: I.Brain, label: "Strongest connection", title: "Food ↔ Travel", body: "8 bookmarks bridge Cooking and Travel. Common thread: local cuisine guides." },
          { icon: I.Eye, label: "Price drop alert", title: "Buy Later watchlist", body: "3 items in your Buy Later list have been saved 30+ days. Still interested?" },
        ]).map((card, i) => {
          const Icon = card.icon;
          return (
            <div key={i} className="card" style={{padding:14}}>
              <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:8}}>
                <div style={{width:22, height:22, borderRadius:6, background:'var(--blue-bg)', color:'var(--blue)', display:'inline-flex', alignItems:'center', justifyContent:'center'}}>
                  <Icon className="icon icon-xs" />
                </div>
                <div style={{fontSize:10, fontWeight:700, color:'var(--text-4)', letterSpacing:'0.08em', textTransform:'uppercase'}}>{card.label}</div>
              </div>
              <div style={{fontSize:13, fontWeight:600, color:'var(--text-1)', marginBottom:4, letterSpacing:'-0.01em'}}>{card.title}</div>
              <div style={{fontSize:11, color:'var(--text-3)', lineHeight:1.5}}>{card.body}</div>
            </div>
          );
        })}
      </div>

      <div style={{height:48}} />
    </div>
  );
}

window.KnowledgeMap = KnowledgeMap;
