/* Mastery map · Japanese mode — frequency-band layout
   Same surface, different domain. Frequency bands replace prerequisite ranks
   as the primary organizing axis. Entity types extend: kanji, vocab, grammar. */

const MasteryMapJapanese = () => {
  const [hovered, setHovered] = React.useState(null);
  const [layout, setLayout] = React.useState("frequency");
  const [filter, setFilter] = React.useState("all");

  // Bands by corpus frequency rank. Each node carries kind, freq rank, FSRS state.
  // Mix of kanji / vocab / grammar to show the typed entity legend extended.
  const nodes = [
    // Top 100
    { id:"k_日",   label:"日",        kind:"kanji",  band:0, x:0.10, y:0.12, mastery:"mastered", retention:0.95, due:18 },
    { id:"v_する", label:"する",      kind:"vocab",  band:0, x:0.22, y:0.10, mastery:"mastered", retention:0.97, due:22 },
    { id:"v_いる", label:"いる",      kind:"vocab",  band:0, x:0.34, y:0.14, mastery:"mastered", retention:0.93, due:14 },
    { id:"g_は",   label:"は · topic", kind:"grammar",band:0, x:0.46, y:0.10, mastery:"mastered", retention:0.96, due:30 },
    { id:"g_を",   label:"を · obj",   kind:"grammar",band:0, x:0.58, y:0.14, mastery:"mastered", retention:0.92, due:12 },
    { id:"v_食べる",label:"食べる",   kind:"vocab",  band:0, x:0.70, y:0.10, mastery:"mastered", retention:0.94, due:35 },
    { id:"k_人",   label:"人",        kind:"kanji",  band:0, x:0.82, y:0.14, mastery:"mastered", retention:0.88, due: 5 },
    { id:"v_見る", label:"見る",      kind:"vocab",  band:0, x:0.92, y:0.10, mastery:"mastered", retention:0.62, due:-3 },

    // 100-500
    { id:"k_動",   label:"動",        kind:"kanji",  band:1, x:0.08, y:0.30, mastery:"learning", retention:0.52, due:-1 },
    { id:"v_行く", label:"行く",      kind:"vocab",  band:1, x:0.20, y:0.28, mastery:"mastered", retention:0.81, due: 6 },
    { id:"k_時",   label:"時",        kind:"kanji",  band:1, x:0.32, y:0.32, mastery:"mastered", retention:0.74, due: 2 },
    { id:"g_て",   label:"て · conj",  kind:"grammar",band:1, x:0.44, y:0.28, mastery:"learning", retention:0.45, due: 0 },
    { id:"v_友達", label:"友達",      kind:"vocab",  band:1, x:0.56, y:0.32, mastery:"mastered", retention:0.79, due: 9 },
    { id:"k_車",   label:"車",        kind:"kanji",  band:1, x:0.68, y:0.28, mastery:"mastered", retention:0.86, due:11 },
    { id:"g_たい", label:"たい · desid",kind:"grammar",band:1,x:0.80, y:0.32, mastery:"mastered", retention:0.55, due:-4 },
    { id:"v_来る", label:"来る",      kind:"vocab",  band:1, x:0.92, y:0.28, mastery:"mastered", retention:0.83, due:13 },

    // 500-1000
    { id:"v_美味しい",label:"美味しい",kind:"vocab", band:2, x:0.10, y:0.46, mastery:"mastered", retention:0.78, due: 3 },
    { id:"k_運",   label:"運",        kind:"kanji",  band:2, x:0.24, y:0.50, mastery:"learning", retention:0.46, due:-2 },
    { id:"v_運動", label:"運動",      kind:"vocab",  band:2, x:0.36, y:0.46, mastery:"mastered", retention:0.71, due: 1 },
    { id:"g_ば",   label:"ば · cond",  kind:"grammar",band:2, x:0.50, y:0.50, mastery:"frontier", retention:null, due:null },
    { id:"v_使う", label:"使う",      kind:"vocab",  band:2, x:0.62, y:0.46, mastery:"frontier", retention:null, due:null },
    { id:"k_新",   label:"新",        kind:"kanji",  band:2, x:0.74, y:0.50, mastery:"frontier", retention:null, due:null, focus:true },
    { id:"v_新しい",label:"新しい",   kind:"vocab",  band:2, x:0.86, y:0.46, mastery:"frontier", retention:null, due:null },

    // 1000-5000
    { id:"k_識",   label:"識",        kind:"kanji",  band:3, x:0.12, y:0.66, mastery:"locked",   retention:null, due:null },
    { id:"v_意識", label:"意識",      kind:"vocab",  band:3, x:0.26, y:0.70, mastery:"locked",   retention:null, due:null },
    { id:"g_させる",label:"させる · caus",kind:"grammar",band:3,x:0.40, y:0.66, mastery:"locked", retention:null, due:null },
    { id:"v_似る", label:"似る",      kind:"vocab",  band:3, x:0.54, y:0.70, mastery:"locked",   retention:null, due:null },
    { id:"k_鏡",   label:"鏡",        kind:"kanji",  band:3, x:0.68, y:0.66, mastery:"locked",   retention:null, due:null },
    { id:"v_鏡",   label:"鏡 · mirror",kind:"vocab", band:3, x:0.82, y:0.70, mastery:"locked",   retention:null, due:null },

    // 5000+
    { id:"k_鬱",   label:"鬱",        kind:"kanji",  band:4, x:0.18, y:0.86, mastery:"locked",   retention:null, due:null },
    { id:"v_憂鬱", label:"憂鬱",      kind:"vocab",  band:4, x:0.36, y:0.90, mastery:"locked",   retention:null, due:null },
    { id:"g_らしい",label:"らしい·hear",kind:"grammar",band:4,x:0.54, y:0.86, mastery:"locked",   retention:null, due:null },
    { id:"k_薔",   label:"薔",        kind:"kanji",  band:4, x:0.72, y:0.90, mastery:"locked",   retention:null, due:null },
    { id:"v_薔薇", label:"薔薇",      kind:"vocab",  band:4, x:0.88, y:0.86, mastery:"locked",   retention:null, due:null },
  ];

  const bands = [
    { id:0, label:"TOP 100",    range:"freq #1–100",     count: nodes.filter(n=>n.band===0).length, y:0.12 },
    { id:1, label:"100 – 500",  range:"core daily",       count: nodes.filter(n=>n.band===1).length, y:0.30 },
    { id:2, label:"500 – 1000", range:"common — frontier",count: nodes.filter(n=>n.band===2).length, y:0.48 },
    { id:3, label:"1K – 5K",    range:"academic",         count: nodes.filter(n=>n.band===3).length, y:0.68 },
    { id:4, label:"5K+",        range:"literary · rare",  count: nodes.filter(n=>n.band===4).length, y:0.88 },
  ];

  const stateOf = (n) => {
    if (n.mastery === "frontier") return "frontier";
    if (n.mastery === "locked")   return "locked";
    if (n.mastery === "learning") return "learning";
    if (n.due !== null && n.due < 0) return "review";
    return "mastered";
  };

  const counts = {
    mastered: nodes.filter(n => stateOf(n)==="mastered").length,
    review:   nodes.filter(n => stateOf(n)==="review").length,
    learning: nodes.filter(n => stateOf(n)==="learning").length,
    frontier: nodes.filter(n => stateOf(n)==="frontier").length,
    locked:   nodes.filter(n => stateOf(n)==="locked").length,
  };
  const matchFilter = (n) => filter === "all" || stateOf(n) === filter;

  const W = 1180, H = 720, PAD_X = 70, PAD_Y = 30;
  const xToPx = (x) => PAD_X + x*(W-2*PAD_X);
  const yToPx = (y) => PAD_Y + y*(H-2*PAD_Y);

  const reviewDue = nodes.filter(n => n.due !== null && n.due < 0).sort((a,b) => a.due - b.due);
  const frontier = nodes.filter(n => n.mastery === "frontier");
  const nodeById = Object.fromEntries(nodes.map(n => [n.id, n]));

  // Shape per kind: kanji=square, vocab=circle, grammar=diamond
  const drawShape = (n, cx, cy) => {
    const st = stateOf(n);
    const fill = st==="mastered" ? "var(--ink)"
              : st==="frontier"  ? "var(--accent)"
              : "var(--paper)";
    const stroke = st==="locked"   ? "var(--rule-2)"
                : st==="frontier"  ? "var(--accent)"
                : "var(--ink)";
    const sw = n.focus ? 2 : 1.25;
    if (n.kind === "kanji") {
      return <rect x={cx-5} y={cy-5} width="10" height="10" fill={fill} stroke={stroke} strokeWidth={sw}/>;
    }
    if (n.kind === "grammar") {
      return <polygon points={`${cx},${cy-6} ${cx+6},${cy} ${cx},${cy+6} ${cx-6},${cy}`}
                       fill={fill} stroke={stroke} strokeWidth={sw}/>;
    }
    return <circle cx={cx} cy={cy} r={n.focus?7:5} fill={fill} stroke={stroke} strokeWidth={sw}/>;
  };

  return (
    <div className="mm">
      <header className="mm__top">
        <div className="mm__top-l">
          <span className="t-mono" style={{color:"var(--ink-4)"}}>§ MAP</span>
          <span className="cp__bc-sep">/</span>
          <span className="cp__bc-cur">Mastery map · 日本語</span>
          <span className="cp__bc-sep">·</span>
          <span className="t-ui" style={{color:"var(--ink-3)"}}>frequency-organized · 32 nodes shown / 14,082 total</span>
        </div>
        <div className="mm__top-r">
          <span className="t-meta">Domain</span>
          <select className="mm__domain" defaultValue="jp">
            <option value="math">mathematics · calculus</option>
            <option value="jp">japanese · vocab + kanji + grammar</option>
          </select>
          <span className="t-meta">Layout</span>
          <div className="pg__viewseg">
            {[["frequency","Frequency"],["jlpt","JLPT"],["radical","Radical"]].map(([k,l]) => (
              <button key={k} className={"pg__viewseg-btn " + (layout===k?"is-on":"")} onClick={()=>setLayout(k)}>{l}</button>
            ))}
          </div>
          <span className="cp__top-divider" />
          <button className="btn cp__top-btn">Start review (3) →</button>
        </div>
      </header>
      <hr className="rule" />

      <div className="mm__layout">
        <aside className="mm__rail mm__rail--l">
          <div className="mm__what">
            <div className="t-meta">Right now</div>
            <hr className="rule-3" />
            <div className="mm__what-card mm__what-card--review">
              <div className="mm__what-head">
                <span className="mastery-dot mastery-dot--review" />
                <span className="t-meta">Review · {reviewDue.length} due</span>
                <span className="t-mono mm__what-time">~6 min</span>
              </div>
              <ul className="mm__what-list">
                {reviewDue.map(n => (
                  <li key={n.id} className="mm__what-item">
                    <span className="t-ui mm__what-label mmj__lang">{n.label}</span>
                    <span className="t-mono mm__what-meta">R {Math.round(n.retention*100)}% · {n.due}d</span>
                  </li>
                ))}
              </ul>
            </div>
            <div className="mm__what-card mm__what-card--frontier">
              <div className="mm__what-head">
                <span className="mastery-dot mastery-dot--frontier" />
                <span className="t-meta">Frontier · {frontier.length}</span>
              </div>
              <ul className="mm__what-list">
                {frontier.slice(0,4).map(n => (
                  <li key={n.id} className="mm__what-item">
                    <span className="t-ui mm__what-label mmj__lang">{n.label}</span>
                    <span className="t-mono mm__what-meta">band 500–1k</span>
                  </li>
                ))}
              </ul>
            </div>
          </div>

          <div className="mm__legend">
            <div className="t-meta">Entity</div>
            <hr className="rule-3" />
            <ul className="mm__legend-list">
              <li><svg width="12" height="12"><rect x="1" y="1" width="10" height="10" fill="var(--ink)" /></svg><span className="t-ui">Kanji</span><span className="t-mono mm__legend-n">{nodes.filter(n=>n.kind==="kanji").length}</span></li>
              <li><svg width="12" height="12"><circle cx="6" cy="6" r="5" fill="var(--ink)"/></svg><span className="t-ui">Vocab</span><span className="t-mono mm__legend-n">{nodes.filter(n=>n.kind==="vocab").length}</span></li>
              <li><svg width="12" height="12"><polygon points="6,1 11,6 6,11 1,6" fill="var(--ink)"/></svg><span className="t-ui">Grammar</span><span className="t-mono mm__legend-n">{nodes.filter(n=>n.kind==="grammar").length}</span></li>
            </ul>
            <hr className="rule-3" style={{margin:"10px 0"}}/>
            <div className="t-meta">State</div>
            <ul className="mm__legend-list" style={{marginTop:"6px"}}>
              <li><span className="mastery-dot mastery-dot--mastered" /><span className="t-ui">Mastered</span><span className="t-mono mm__legend-n">{counts.mastered}</span></li>
              <li><span className="mastery-dot mastery-dot--review" /><span className="t-ui">Review due</span><span className="t-mono mm__legend-n">{counts.review}</span></li>
              <li><span className="mastery-dot mastery-dot--learning" /><span className="t-ui">Learning</span><span className="t-mono mm__legend-n">{counts.learning}</span></li>
              <li><span className="mastery-dot mastery-dot--frontier" /><span className="t-ui">Frontier</span><span className="t-mono mm__legend-n">{counts.frontier}</span></li>
              <li><span className="mastery-dot mastery-dot--locked" /><span className="t-ui">Locked</span><span className="t-mono mm__legend-n">{counts.locked}</span></li>
            </ul>
            <div className="mm__filter">
              {["all","review","frontier","learning"].map(k => (
                <button key={k} className={"mm__filter-btn " + (filter===k?"is-on":"")} onClick={()=>setFilter(k)}>{k}</button>
              ))}
            </div>
          </div>
        </aside>

        <div className="mm__stage">
          <svg viewBox={`0 0 ${W} ${H}`} className="mm__svg" preserveAspectRatio="xMidYMid meet">
            <defs>
              <radialGradient id="mmj-frontier" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0" stopColor="var(--accent)" stopOpacity="0.18"/>
                <stop offset="1" stopColor="var(--accent)" stopOpacity="0"/>
              </radialGradient>
            </defs>

            {/* Frequency bands as horizontal bars */}
            {bands.map((b, i) => (
              <g key={b.id}>
                <line x1={PAD_X} y1={yToPx(b.y - 0.04)} x2={W-PAD_X} y2={yToPx(b.y - 0.04)}
                      stroke="var(--rule-3)" strokeWidth="0.5" strokeDasharray="2 4"/>
                <text x={PAD_X} y={yToPx(b.y - 0.06)+4}
                      fontFamily="var(--font-mono)" fontSize="9" fill="var(--ink-4)" letterSpacing="1">
                  {b.label} · {b.range} · {b.count}
                </text>
                {/* density indicator on right */}
                <text x={W-PAD_X} y={yToPx(b.y - 0.06)+4} textAnchor="end"
                      fontFamily="var(--font-mono)" fontSize="9" fill="var(--ink-5)">
                  {b.id === 0 ? "essentials" : b.id === 4 ? "long tail" : ""}
                </text>
              </g>
            ))}

            {/* Frontier glow */}
            {nodes.filter(n => stateOf(n) === "frontier").map(n => (
              <circle key={"g-"+n.id} cx={xToPx(n.x)} cy={yToPx(n.y)} r="44" fill="url(#mmj-frontier)" />
            ))}

            {/* Lateral connections — kanji↔vocab containment */}
            <g opacity="0.4">
              <line x1={xToPx(0.08)} y1={yToPx(0.30)} x2={xToPx(0.36)} y2={yToPx(0.46)} stroke="var(--rule-2)" strokeWidth="0.6"/>
              <line x1={xToPx(0.74)} y1={yToPx(0.50)} x2={xToPx(0.86)} y2={yToPx(0.46)} stroke="var(--accent)" strokeWidth="0.8"/>
              <line x1={xToPx(0.12)} y1={yToPx(0.66)} x2={xToPx(0.26)} y2={yToPx(0.70)} stroke="var(--rule-2)" strokeWidth="0.6"/>
              <line x1={xToPx(0.68)} y1={yToPx(0.66)} x2={xToPx(0.82)} y2={yToPx(0.70)} stroke="var(--rule-2)" strokeWidth="0.6"/>
              <line x1={xToPx(0.18)} y1={yToPx(0.86)} x2={xToPx(0.36)} y2={yToPx(0.90)} stroke="var(--rule-2)" strokeWidth="0.6"/>
              <line x1={xToPx(0.72)} y1={yToPx(0.90)} x2={xToPx(0.88)} y2={yToPx(0.86)} stroke="var(--rule-2)" strokeWidth="0.6"/>
            </g>

            {/* Nodes */}
            {nodes.map(n => {
              const cx = xToPx(n.x), cy = yToPx(n.y);
              const dim = filter !== "all" && !matchFilter(n);
              const st = stateOf(n);
              return (
                <g key={n.id}
                   onMouseEnter={()=>setHovered(n.id)}
                   onMouseLeave={()=>setHovered(null)}
                   style={{cursor:"pointer"}}
                   opacity={dim ? 0.18 : 1}>
                  {drawShape(n, cx, cy)}
                  {st === "review" && <circle cx={cx} cy={cy} r="2.5" fill="var(--ink)"/>}
                  {n.focus && <circle cx={cx} cy={cy} r="14" fill="none" stroke="var(--accent)" strokeWidth="1" strokeDasharray="2 2"/>}
                  {n.retention !== null && st !== "frontier" && (
                    <g transform={`translate(${cx-12},${cy+10})`}>
                      <line x1="0" y1="0" x2="24" y2="0" stroke="var(--rule-3)" strokeWidth="2"/>
                      <line x1="0" y1="0" x2={24*n.retention} y2="0"
                            stroke={st === "review" ? "var(--accent)" : "var(--ink)"} strokeWidth="2"/>
                    </g>
                  )}
                  <text x={cx + 9} y={cy + 4}
                        fontFamily="var(--font-jp), var(--font-ui)" fontSize="11"
                        fontWeight={n.focus?600:500}
                        fill={st === "locked" ? "var(--ink-4)" : "var(--ink)"}>
                    {n.label}
                  </text>
                </g>
              );
            })}
          </svg>
        </div>

        <aside className="mm__rail mm__rail--r">
          <div className="t-meta">Selected</div>
          <hr className="rule-3" />
          {hovered ? (() => {
            const n = nodeById[hovered]; const st = stateOf(n);
            return (
              <div className="mm__sel">
                <div className="mm__sel-head">
                  <span className={"mastery-dot mastery-dot--" + st} />
                  <span className="type-chip" data-kind={n.kind==="kanji"?"definition":n.kind==="grammar"?"theorem":"definition"}>{n.kind}</span>
                </div>
                <h3 className="t-h3 mm__sel-title mmj__lang" style={{fontSize:"32px"}}>{n.label}</h3>
                <div className="t-mono mm__sel-id">{n.kind}.jp.{n.id.split("_")[1]}</div>
                <hr className="rule-3" style={{margin:"14px 0"}}/>
                <div className="mm__sel-row"><span className="t-meta">Frequency band</span><span className="t-mono">{bands[n.band].label}</span></div>
                {n.retention !== null ? (
                  <>
                    <div className="mm__sel-row"><span className="t-meta">FSRS retention</span><span className="t-mono">{Math.round(n.retention*100)}%</span></div>
                    <div className="mm__sel-row"><span className="t-meta">Due</span><span className="t-mono" style={{color: n.due<0?"var(--accent)":"var(--ink)"}}>{n.due<0?`${-n.due}d ago`:`in ${n.due}d`}</span></div>
                    <div className="mm__sel-row"><span className="t-meta">Stability</span><span className="t-mono">14.2d</span></div>
                  </>
                ) : (
                  <div className="t-ui" style={{color:"var(--ink-3)",fontStyle:"italic",marginTop:"6px"}}>{st==="frontier"?"Ready to learn — adjacent concepts mastered.":"Not yet within reach."}</div>
                )}
                <hr className="rule-3" style={{margin:"14px 0"}}/>
                <button className="btn cp__top-btn" style={{width:"100%",justifyContent:"center"}}>
                  {st==="frontier"?"Begin →":st==="review"?"Review now →":"Open →"}
                </button>
              </div>
            );
          })() : (
            <div className="t-ui mm__sel-empty">
              Hover any glyph for state.
              <hr className="rule-3" style={{margin:"18px 0"}}/>
              <div className="t-meta" style={{marginBottom:"6px"}}>Domain progress</div>
              <div className="t-display" style={{fontSize:"56px",lineHeight:1,color:"var(--ink)"}}>1,041</div>
              <div className="t-meta" style={{marginTop:"4px"}}>kanji · vocab · grammar mastered</div>
              <hr className="rule-3" style={{margin:"18px 0"}}/>
              <div className="t-meta" style={{marginBottom:"6px"}}>JLPT projection</div>
              <div className="mm__sel-row"><span className="t-ui">N5</span><span className="t-mono">100% · cleared</span></div>
              <div className="mm__sel-row"><span className="t-ui">N4</span><span className="t-mono">86%</span></div>
              <div className="mm__sel-row"><span className="t-ui">N3</span><span className="t-mono">41%</span></div>
              <div className="mm__sel-row"><span className="t-ui">N2</span><span className="t-mono">9%</span></div>
              <hr className="rule-3" style={{margin:"18px 0"}}/>
              <div className="t-meta">Today</div>
              <div className="mm__sel-row"><span className="t-ui">Reviews due</span><span className="t-mono">3</span></div>
              <div className="mm__sel-row"><span className="t-ui">New (frontier)</span><span className="t-mono">4</span></div>
              <div className="mm__sel-row"><span className="t-ui">Avg retention</span><span className="t-mono">71%</span></div>
            </div>
          )}
        </aside>
      </div>

      <hr className="rule-2" />
      <footer className="pg__foot">
        <span className="t-meta">{nodes.length} of 14,082 nodes shown · domain: japanese · layout: {layout}</span>
        <span className="t-mono" style={{color:"var(--ink-4)"}}>FSRS-6 · personalized · last sync 09:14 JST</span>
      </footer>
    </div>
  );
};

window.MasteryMapJapanese = MasteryMapJapanese;
