// Sales / Downloads dashboard page

function WorldMap({ countries, onHover, hovered }) {
  // simple equirectangular projection onto 1000x500 SVG
  const project = (lat, lng) => {
    const x = (lng + 180) * (1000 / 360);
    const y = (90 - lat) * (500 / 180);
    return [x, y];
  };
  const max = Math.max(...countries.map(c => c.dl));
  return (
    <svg viewBox="0 0 1000 500" className="chart-svg" style={{maxHeight: 460, background:"var(--bg-surface-alt)", borderRadius:12}}>
      {/* subtle grid */}
      {[-60,-30,0,30,60].map(lat => {
        const [, y] = project(lat, 0);
        return <line key={"h"+lat} x1="0" x2="1000" y1={y} y2={y} stroke="var(--chart-grid)" strokeWidth="0.5" strokeDasharray="3 4" />;
      })}
      {[-120,-60,0,60,120].map(lng => {
        const [x] = project(0, lng);
        return <line key={"v"+lng} x1={x} x2={x} y1="0" y2="500" stroke="var(--chart-grid)" strokeWidth="0.5" strokeDasharray="3 4" />;
      })}
      {/* country markers */}
      {countries.map(c => {
        const [x, y] = project(c.lat, c.lng);
        const r = 4 + Math.sqrt(c.dl / max) * 36;
        const isKR = c.code === "KR";
        const isHover = hovered && hovered.code === c.code;
        return (
          <g key={c.code} style={{cursor:"pointer"}} onMouseEnter={() => onHover(c)} onMouseLeave={() => onHover(null)}>
            <circle cx={x} cy={y} r={r+6} fill={isKR ? "var(--accent)" : "var(--accent-amber-500)"} opacity={isHover ? 0.25 : 0.1}>
              {isKR && <animate attributeName="r" values={`${r+4};${r+12};${r+4}`} dur="3s" repeatCount="indefinite" />}
              {isKR && <animate attributeName="opacity" values="0.15;0.02;0.15" dur="3s" repeatCount="indefinite" />}
            </circle>
            <circle cx={x} cy={y} r={r} fill={isKR ? "var(--accent)" : "var(--accent-amber-500)"} opacity="0.75" stroke="var(--bg-surface)" strokeWidth="1" />
          </g>
        );
      })}
      {/* labels for top 4 */}
      {countries.slice(0, 4).map(c => {
        const [x, y] = project(c.lat, c.lng);
        return (
          <g key={"l"+c.code}>
            <text x={x + 10} y={y - 8} fontSize="11" fontWeight="700" fill="var(--fg-default)" fontFamily="var(--font-mono)">
              {c.flag} {c.name}
            </text>
            <text x={x + 10} y={y + 6} fontSize="9" fill="var(--fg-muted)" fontFamily="var(--font-mono)">
              {(c.dl/1000).toFixed(0)}k
            </text>
          </g>
        );
      })}
    </svg>
  );
}

function RadialBars({ data, size = 260 }) {
  const cx = 100, cy = 100, rings = data.length;
  const max = Math.max(...data.map(d => d.v));
  // 피크(2018) 연도를 amber로 강조
  const peakIdx = data.reduce((best, d, i) => d.v > data[best].v ? i : best, 0);
  return (
    <div style={{display:"flex", gap:24, alignItems:"center", justifyContent:"center", flexWrap:"wrap"}}>
      <svg viewBox="0 0 200 200" width={size} height={size}>
        {data.map((d, i) => {
          const r = 18 + (rings - i) * 7;
          const pct = d.v / max;
          const circ = 2 * Math.PI * r;
          const isPeak = i === peakIdx;
          return (
            <g key={d.y}>
              <circle cx={cx} cy={cy} r={r} fill="none" stroke="var(--bg-surface-alt)" strokeWidth="5" />
              <circle cx={cx} cy={cy} r={r} fill="none"
                stroke={isPeak ? "var(--accent-amber-500)" : "var(--accent)"}
                strokeWidth="5"
                strokeDasharray={`${pct * circ} ${circ}`}
                strokeLinecap="round"
                transform={`rotate(-90 ${cx} ${cy})`}
                opacity={isPeak ? 1 : 0.85}
                style={{transition: "stroke-dasharray 800ms var(--ease-out)"}}
              />
            </g>
          );
        })}
      </svg>
      <ul style={{
        listStyle:"none", margin:0, padding:0,
        display:"grid", gridTemplateColumns:"repeat(2, minmax(80px, auto))",
        gap:"4px 16px", fontSize:12, minWidth:180,
      }}>
        {data.map((d, i) => {
          const isPeak = i === peakIdx;
          return (
            <li key={d.y} style={{display:"flex", alignItems:"center", gap:8, fontFamily:"var(--font-mono)"}}>
              <span style={{
                width:8, height:8, borderRadius:"50%",
                background: isPeak ? "var(--accent-amber-500)" : "var(--accent)",
                flexShrink:0,
              }}></span>
              <span style={{color: isPeak ? "var(--accent-amber-500)" : "var(--fg-default)", fontWeight:700}}>{d.y}</span>
              <span style={{color:"var(--fg-muted)", marginLeft:"auto"}}>{(d.v/10000).toFixed(1)}만</span>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function StackedBars({ bySource }) {
  const total = bySource.reduce((s, d) => s + d.v, 0);
  let acc = 0;
  return (
    <div>
      <div style={{display:"flex", height:28, borderRadius:6, overflow:"hidden", background:"var(--bg-surface-alt)"}}>
        {bySource.map(s => {
          const w = (s.v / total) * 100;
          const el = <div key={s.label} style={{width: `${w}%`, background: s.color, transition:"width 600ms var(--ease-out)"}}></div>;
          acc += w;
          return el;
        })}
      </div>
      <div style={{display:"flex", flexWrap:"wrap", gap:"10px 20px", marginTop:14, fontSize:12}}>
        {bySource.map(s => (
          <div key={s.label} style={{display:"flex", alignItems:"center", gap:6}}>
            <div style={{width:10, height:10, borderRadius:3, background:s.color}}></div>
            <span style={{color:"var(--fg-default)"}}>{s.label}</span>
            <span className="mono" style={{color:"var(--fg-muted)"}}>${s.v.toLocaleString("en-US")}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function RevenueLine({ byYear }) {
  const w = 520, h = 180, pad = 36;
  const max = Math.max(...byYear.map(d => d.v));
  const pts = byYear.map((d, i) => {
    const x = pad + (i / Math.max(1, byYear.length - 1)) * (w - pad*2);
    const y = pad + (h - pad*2) - (d.v / max) * (h - pad*2 - 10);
    return [x, y, d];
  });
  const path = pts.map((p, i) => (i===0?"M":"L") + p[0].toFixed(2) + "," + p[1].toFixed(2)).join(" ");
  return (
    <svg viewBox={`0 0 ${w} ${h + 28}`} className="chart-svg" style={{maxHeight: 220, width:"100%"}}>
      {[0.25, 0.5, 0.75].map((t, i) => {
        const y = pad + (h - pad*2) * (1 - t);
        return <line key={i} x1={pad} x2={w-pad} y1={y} y2={y} stroke="var(--chart-grid)" strokeWidth="0.6" strokeDasharray="2 3" />;
      })}
      <path d={path} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
      {pts.map((p, i) => (
        <g key={i}>
          <circle cx={p[0]} cy={p[1]} r="3.5" fill="var(--bg-surface)" stroke="var(--accent)" strokeWidth="2" />
          <text x={p[0]} y={h + 4} fontSize="11" textAnchor="middle" fill="var(--fg-muted)" fontFamily="var(--font-mono)">
            {p[2].y}
          </text>
        </g>
      ))}
    </svg>
  );
}

function YearlyStackChart({ yearly }) {
  const w = 520, h = 220, pad = 36;
  const max = Math.max(...yearly.map(d => d.dl));
  const bw = (w - pad*2) / yearly.length - 8;
  return (
    <svg viewBox={`0 0 ${w} ${h+40}`} className="chart-svg" style={{maxHeight: 320}}>
      {/* axis grid */}
      {[0,0.25,0.5,0.75,1].map((t, i) => {
        const y = pad + (h - pad*2) * (1 - t);
        return (
          <g key={i}>
            <line x1={pad} x2={w-pad} y1={y} y2={y} stroke="var(--chart-grid)" strokeWidth="0.5" strokeDasharray="2 3" />
            <text x={pad - 6} y={y + 3} textAnchor="end" fontSize="9" fill="var(--fg-subtle)" fontFamily="var(--font-mono)">
              {t === 0 ? "0" : `${((max * t)/10000).toFixed(0)}만`}
            </text>
          </g>
        );
      })}
      {yearly.map((d, i) => {
        const x = pad + i * ((w - pad*2) / yearly.length) + 4;
        const bh = (d.dl / max) * (h - pad*2);
        const y = pad + (h - pad*2) - bh;
        const isPeak = d.y === 2018;
        return (
          <g key={d.y}>
            <rect x={x} y={y} width={bw} height={bh}
              fill={isPeak ? "var(--accent)" : "var(--brand-mint-300)"}
              rx="3"
              style={{transition:"height 700ms var(--ease-out)"}}
            />
            <text x={x + bw/2} y={y - 6} textAnchor="middle" fontSize="9" fontWeight="700" fill="var(--fg-default)" fontFamily="var(--font-mono)">
              {(d.dl/10000).toFixed(0)}만
            </text>
            <text x={x + bw/2} y={pad + (h-pad*2) + 18} textAnchor="middle" fontSize="10" fill="var(--fg-muted)" fontFamily="var(--font-mono)">
              {d.y}
            </text>
            {isPeak && (
              <text x={x + bw/2} y={pad + (h-pad*2) + 32} textAnchor="middle" fontSize="9" fill="var(--accent)" fontWeight="700">
                ★ 정점
              </text>
            )}
          </g>
        );
      })}
    </svg>
  );
}

function DownloadHeatmap({ heatmap, years }) {
  const max = Math.max(...heatmap.flatMap(r => r.data));
  return (
    <div>
      <div className="heatmap-header">
        {years.map(y => <div key={y} className="heatmap-header-cell">{y}</div>)}
      </div>
      {heatmap.map(row => (
        <div key={row.m} className="heatmap-row">
          <div className="heatmap-label">{row.m}</div>
          {row.data.map((v, i) => {
            const ratio = v / max;
            let bg = "var(--heat-0)";
            if (v > 0) {
              if (ratio < 0.15) bg = "var(--heat-1)";
              else if (ratio < 0.35) bg = "var(--heat-2)";
              else if (ratio < 0.55) bg = "var(--heat-3)";
              else if (ratio < 0.8) bg = "var(--heat-4)";
              else bg = "var(--heat-5)";
            }
            return (
              <div key={i} className="heatmap-cell" style={{background: bg}} title={`${years[i]} · ${row.m} · ${v}k DL`}></div>
            );
          })}
        </div>
      ))}
    </div>
  );
}

function SalesPage() {
  const S = window.SALES_DATA;
  const [hoveredCountry, setHoveredCountry] = React.useState(null);

  return (
    <div className="page">
      <section className="reviews-hero">
        <div style={{fontSize:12, letterSpacing:"0.18em", fontWeight:600, textTransform:"uppercase", color:"var(--fg-muted)", marginBottom:16}}>
          판매 지도 · Sales Map
        </div>
        <h1>261만 번, <em style={{fontStyle:"normal", color:"var(--accent)"}}>164</em>개국</h1>
        <p className="reviews-hero-sub">앱이 설치된 장소와 시간의 기록</p>
      </section>

      <section>
        <div className="kpi-grid">
          {S.kpis.map((k, i) => <KpiCard key={i} {...k} />)}
        </div>
      </section>

      {/* WORLD MAP */}
      <section className="section">
        <h2 className="section-title">어디에 도착했나</h2>
        <p className="section-sub">원의 크기는 다운로드 수. 대한민국이 89.9%를 차지한다.</p>
        <div className="chart-card" style={{padding:"20px 24px"}}>
          <WorldMap countries={S.countries} onHover={setHoveredCountry} hovered={hoveredCountry} />
          <div className="map-legend">
            <div className="map-legend-row">
              <div className="dot" style={{background:"var(--accent)"}}></div>
              <span>대한민국 (기준)</span>
            </div>
            <div className="map-legend-row">
              <div className="dot" style={{background:"var(--accent-amber-500)"}}></div>
              <span>해외 · 163개국</span>
            </div>
            {hoveredCountry && (
              <div className="map-tooltip">
                <div style={{fontSize:14, fontWeight:700}}>{hoveredCountry.flag} {hoveredCountry.name}</div>
                <div className="mono" style={{color:"var(--accent)", fontSize:13, marginTop:4}}>
                  {hoveredCountry.dl.toLocaleString("ko-KR")} DL
                </div>
                <div className="mono" style={{color:"var(--fg-muted)", fontSize:11}}>
                  리뷰 {hoveredCountry.rev.toLocaleString("ko-KR")}건
                </div>
              </div>
            )}
          </div>
        </div>

        {/* country list */}
        <div style={{marginTop:16}} className="country-grid">
          {S.countries.map(c => (
            <div key={c.code} className="country-card"
              onMouseEnter={() => setHoveredCountry(c)}
              onMouseLeave={() => setHoveredCountry(null)}
            >
              <div style={{fontSize:22}}>{c.flag}</div>
              <div style={{flex:1}}>
                <div style={{fontWeight:600, fontSize:13}}>{c.name}</div>
                <div className="mono" style={{fontSize:11, color:"var(--fg-muted)"}}>
                  {c.dl.toLocaleString("ko-KR")}
                </div>
              </div>
              <div style={{fontSize:10, color:"var(--fg-subtle)", fontFamily:"var(--font-mono)"}}>
                {((c.dl / S.countries[0].dl) * 100).toFixed(1)}%
              </div>
            </div>
          ))}
        </div>
      </section>

      {/* YEARLY CHART */}
      <section className="section">
        <h2 className="section-title">10년의 곡선</h2>
        <p className="section-sub">2018년이 가장 높은 해였다. 그 이후로 완만하게 내려왔다.</p>
        <div className="chart-card">
          <YearlyStackChart yearly={S.yearly} />
          <div className="yearly-notes">
            {S.yearly.map(y => (
              <div key={y.y} className="yearly-note">
                <div className="mono" style={{color:"var(--accent)", fontSize:11, fontWeight:700}}>{y.y}</div>
                <div style={{fontSize:12, color:"var(--fg-muted)"}}>{y.note}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* HEATMAP + RADIAL */}
      <section className="section">
        <div className="charts-row">
          <div className="chart-card">
            <div className="chart-card-head">
              <h4 className="chart-title">월별 다운로드 히트맵</h4>
              <span className="caption muted">k 단위</span>
            </div>
            <p className="chart-sub">개학 시즌(3월·9월)과 연말 결심 시즌에 물결이 뚜렷했다.</p>
            <DownloadHeatmap heatmap={S.heatmap} years={S.heatmapYears} />
          </div>

          <div className="chart-card">
            <div className="chart-card-head">
              <h4 className="chart-title">연간 방사 차트</h4>
              <span className="caption muted">동심원</span>
            </div>
            <p className="chart-sub">중심에서 바깥으로 시간이 흐른다.</p>
            <div style={{display:"grid", placeItems:"center", padding:"12px 0"}}>
              <RadialBars data={S.yearly.map(y => ({y:y.y, v:y.dl}))} size={260} />
            </div>
          </div>
        </div>
      </section>

      {/* REVENUE */}
      <section className="section">
        <h2 className="section-title">돈의 흐름</h2>
        <p className="section-sub">수익은 2018년 이후 조용히 쌓였다. 총 ₩97,200,000 (≈ $74,300).</p>

        <div className="charts-row">
          <div className="chart-card">
            <div className="chart-card-head">
              <h4 className="chart-title">수익 구성</h4>
            </div>
            <p className="chart-sub">인앱 구매가 대부분, 기부가 얇게 섞였다.</p>
            <div style={{marginTop:20}}>
              <StackedBars bySource={S.revenue.bySource} />
            </div>
            <div style={{marginTop:28, padding:"16px 18px", background:"var(--bg-surface-alt)", borderRadius:10, display:"flex", justifyContent:"space-between", gap:16, flexWrap:"wrap"}}>
              <div>
                <div className="micro" style={{color:"var(--fg-muted)"}}>원화 기준 (합계)</div>
                <div className="mono" style={{fontSize:22, fontWeight:700, color:"var(--accent)"}}>
                  ₩{S.revenue.totalKRW.toLocaleString("ko-KR")}
                </div>
              </div>
              <div>
                <div className="micro" style={{color:"var(--fg-muted)"}}>달러 환산 (1,300₩/$)</div>
                <div className="mono" style={{fontSize:22, fontWeight:700, color:"var(--fg-default)"}}>
                  ${S.revenue.totalUSD.toLocaleString("en-US")}
                </div>
              </div>
            </div>
          </div>

          <div className="chart-card">
            <div className="chart-card-head">
              <h4 className="chart-title">연도별 수익</h4>
              <span className="caption muted">KRW · 원화</span>
            </div>
            <p className="chart-sub">2021년 정점. 이후 서서히 감소.</p>
            <RevenueLine byYear={S.revenue.byYear} />
            <div className="revenue-notes">
              {S.revenue.byYear.map(y => (
                <div key={y.y} className="revenue-note">
                  <div style={{fontSize:11, color:"var(--fg-muted)", fontFamily:"var(--font-mono)"}}>{y.y}</div>
                  <div style={{fontSize:13, fontWeight:700, color:"var(--fg-default)"}} className="mono">
                    ₩{(y.v/10000).toFixed(0)}만
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>

      <section className="epilogue" style={{marginTop:96}}>
        <div className="epilogue-quote">"숫자는 거리를 숨기지 못한다."</div>
        <div style={{color:"var(--fg-muted)", fontSize:14, maxWidth:"44ch", margin:"0 auto"}}>
          261만 개의 설치. 그 중 89.9%가 한국이었지만, 10.1%는 바다 건너에서 왔다.
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { SalesPage });
