/* global React, Icon, Reveal, TiltCard, CountUp */
const { useState: useFW, useEffect: useFWE, useRef: useFWR } = React;

/* =========================================================
   Live ticker — animated number that randomly pulses
   ========================================================= */
function LiveTicker({ base = 23400, jitter = 80, label = "Live reserves" }) {
  const [v, setV] = useFW(base);
  useFWE(() => {
    const id = setInterval(() => {
      setV(b => base + Math.round((Math.random() - 0.3) * jitter));
    }, 1800);
    return () => clearInterval(id);
  }, [base, jitter]);
  return (
    <div className="fw-ticker">
      <div className="fw-ticker-head">
        <span className="live-dot"></span>
        <span className="metric-label">{label}</span>
      </div>
      <div className="fw-ticker-value flicker-up" key={v}>
        ${v.toLocaleString()}
      </div>
      <div className="metric-sub">refreshed every 1.8s · simulated</div>
    </div>
  );
}

/* =========================================================
   Income source allocator — interactive pie/donut
   ========================================================= */
function AllocatorWidget() {
  const [income, setIncome] = useFW(8500);
  const tiers = [
    { name: "Survival",       pct: 42, color: "#d44a4a", desc: "Rent, utilities, food, minimums" },
    { name: "Business ops",   pct: 18, color: "#e98835", desc: "Tools, contractors, marketing" },
    { name: "Tax reserve",    pct: 22, color: "#e8b53b", desc: "Auto-set for quarterly est." },
    { name: "Growth",         pct:  8, color: "#2e9143", desc: "Reinvest, education, gear" },
    { name: "Lifestyle",      pct:  5, color: "#3a8dde", desc: "Discretionary, dining, fun" },
    { name: "Wealth",         pct:  5, color: "#8c5cd6", desc: "Savings, investments" },
  ];
  // Donut math
  const r = 70, c = 2 * Math.PI * r;
  let acc = 0;
  return (
    <div className="fw-allocator">
      <div className="fw-alloc-head">
        <div>
          <div className="metric-label">"What if" income simulator</div>
          <div style={{fontSize:13, color:"var(--charcoal-500)"}}>Drag to see how each deposit auto-distributes</div>
        </div>
        <div className="fw-alloc-amount">${income.toLocaleString()}</div>
      </div>
      <input
        type="range" min="500" max="20000" step="100" value={income}
        onChange={e => setIncome(+e.target.value)}
        className="fw-range"
      />
      <div className="fw-alloc-body">
        <svg viewBox="0 0 180 180" className="fw-donut">
          <circle cx="90" cy="90" r={r} stroke="var(--gray-100)" strokeWidth="22" fill="none"/>
          {tiers.map((t,i) => {
            const len = (t.pct/100) * c;
            const off = -((acc/100) * c);
            acc += t.pct;
            return (
              <circle key={i} cx="90" cy="90" r={r}
                stroke={t.color} strokeWidth="22" fill="none"
                strokeDasharray={`${len} ${c}`}
                strokeDashoffset={off}
                transform="rotate(-90 90 90)"
                style={{transition:"all .5s cubic-bezier(.2,.6,.2,1)"}}/>
            );
          })}
          <text x="90" y="86" textAnchor="middle" fontFamily="var(--font-display)" fontWeight="700" fontSize="20" fill="var(--charcoal-900)">${(income/1000).toFixed(1)}K</text>
          <text x="90" y="104" textAnchor="middle" fontFamily="var(--font-body)" fontSize="9" fill="var(--charcoal-500)" letterSpacing="0.1em">DEPOSIT</text>
        </svg>
        <div className="fw-alloc-list">
          {tiers.map((t,i) => (
            <div key={i} className="fw-alloc-row">
              <span className="fw-alloc-dot" style={{background:t.color}}></span>
              <div className="fw-alloc-name">
                <div>{t.name}</div>
                <div className="fw-alloc-desc">{t.desc}</div>
              </div>
              <div className="fw-alloc-pct">{t.pct}%</div>
              <div className="fw-alloc-val">${Math.round(income*t.pct/100).toLocaleString()}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* =========================================================
   KPI strip — animated counters with sparklines
   ========================================================= */
function KPIStrip() {
  const items = [
    { label: "Total reserves",    value: 23400, prefix: "$", spark: [12,14,15,16,18,20,21,23], color: "var(--green-600)" },
    { label: "Runway",            value: 8.4,   suffix: " mo", decimals: 1, spark: [4,5,5,6,7,7,8,8.4], color: "#3a4068" },
    { label: "Pipeline (90d)",    value: 41200, prefix: "$",   spark: [30,32,34,36,38,40,40,41], color: "var(--green-500)" },
    { label: "Tax reserved YTD",  value: 14300, prefix: "$",   spark: [2,4,6,8,10,11,13,14], color: "#e8b53b" },
    { label: "Health score",      value: 86,    suffix: "/100",spark: [70,72,74,76,80,82,84,86], color: "var(--green-700)" },
  ];
  return (
    <div className="fw-kpis">
      {items.map((it,i) => (
        <div key={i} className="fw-kpi">
          <div className="metric-label">{it.label}</div>
          <div className="fw-kpi-value">
            <CountUp to={it.value} prefix={it.prefix||""} suffix={it.suffix||""} decimals={it.decimals||0}/>
          </div>
          <svg viewBox="0 0 100 30" className="fw-kpi-spark" preserveAspectRatio="none">
            <defs>
              <linearGradient id={`kpiG${i}`} x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor={it.color} stopOpacity="0.35"/>
                <stop offset="100%" stopColor={it.color} stopOpacity="0"/>
              </linearGradient>
            </defs>
            {(() => {
              const min = Math.min(...it.spark), max = Math.max(...it.spark), range = max-min || 1;
              const pts = it.spark.map((v,j) => `${(j*100/(it.spark.length-1)).toFixed(1)},${(28 - ((v-min)/range)*24).toFixed(1)}`);
              const line = "M " + pts.join(" L ");
              const area = line + ` L 100,30 L 0,30 Z`;
              return <>
                <path d={area} fill={`url(#kpiG${i})`}/>
                <path d={line} fill="none" stroke={it.color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
                <circle cx="100" cy={28 - ((it.spark[it.spark.length-1]-min)/range)*24} r="2.5" fill={it.color}/>
              </>;
            })()}
          </svg>
        </div>
      ))}
    </div>
  );
}

/* =========================================================
   Income stream stacked bar chart
   ========================================================= */
function IncomeStreamsChart() {
  const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  const streams = [
    { name: "Client retainers", color: "var(--green-700)", data: [3.2,3.2,3.2,3.4,3.4,3.6,3.6,3.6,3.8,3.8,4.0,4.0] },
    { name: "Project revenue",  color: "var(--green-500)", data: [2.1,1.4,3.6,2.8,4.5,3.2,5.1,4.4,3.9,5.6,4.8,6.2] },
    { name: "Commissions",      color: "var(--green-400)", data: [0.8,1.2,0.6,1.4,2.1,1.6,2.4,1.8,2.0,2.6,2.2,3.0] },
    { name: "Side hustle",      color: "var(--green-200)", data: [0.4,0.5,0.6,0.4,0.7,0.5,0.8,0.6,0.7,0.9,0.8,1.0] },
  ];
  const totals = months.map((_,i) => streams.reduce((s,st) => s + st.data[i], 0));
  const max = Math.max(...totals);
  const W = 720, H = 220, P = 30;
  const bw = (W - P*2) / months.length * 0.7;
  const gap = (W - P*2) / months.length * 0.3;

  const [hover, setHover] = useFW(null);

  return (
    <div className="fw-streams">
      <div className="fw-streams-head">
        <div>
          <div className="metric-label">Income by stream · last 12 months</div>
          <div className="fw-streams-total">
            <CountUp to={Math.round(totals.reduce((a,b)=>a+b,0)*1000)} prefix="$"/>
            <span className="metric-sub" style={{marginLeft:8, fontWeight:400}}>annual revenue</span>
          </div>
        </div>
        <div className="fw-streams-legend">
          {streams.map((s,i) => (
            <div key={i} className="fw-stream-leg">
              <span style={{background:s.color}}></span>{s.name}
            </div>
          ))}
        </div>
      </div>
      <svg viewBox={`0 0 ${W} ${H+30}`} className="fw-streams-svg">
        {[0,0.25,0.5,0.75,1].map((p,i) => (
          <g key={i}>
            <line x1={P} x2={W-P} y1={H-P-p*(H-P*2)} y2={H-P-p*(H-P*2)} stroke="var(--gray-100)" strokeWidth="1"/>
            <text x={P-6} y={H-P-p*(H-P*2)+4} textAnchor="end" fontSize="9" fill="var(--charcoal-500)">${(p*max).toFixed(1)}K</text>
          </g>
        ))}
        {months.map((m,i) => {
          let yAcc = 0;
          const x = P + i * ((W-P*2)/months.length) + gap/2;
          return (
            <g key={i} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}
               style={{cursor:"pointer"}}>
              <rect x={x} y={P-10} width={bw} height={H-P*2+10} fill={hover===i ? "rgba(76,175,99,0.06)" : "transparent"}/>
              {streams.map((st,j) => {
                const v = st.data[i];
                const h = (v / max) * (H - P*2);
                yAcc += h;
                return (
                  <rect key={j} x={x} y={H-P-yAcc} width={bw} height={h-1}
                        fill={st.color}
                        style={{transition:"opacity .25s"}}
                        opacity={hover === null || hover === i ? 1 : 0.4}/>
                );
              })}
              <text x={x+bw/2} y={H-12} textAnchor="middle" fontSize="10" fill="var(--charcoal-500)" fontFamily="var(--font-display)">{m}</text>
              {hover === i && (
                <g>
                  <rect x={x+bw/2-44} y={H-P-yAcc-32} width="88" height="22" rx="4" fill="var(--charcoal-900)"/>
                  <text x={x+bw/2} y={H-P-yAcc-17} textAnchor="middle" fontSize="11" fill="#fff" fontFamily="var(--font-display)" fontWeight="600">${totals[i].toFixed(1)}K</text>
                </g>
              )}
            </g>
          );
        })}
      </svg>
    </div>
  );
}

/* =========================================================
   Pipeline confidence widget — confirmed/likely/speculative
   ========================================================= */
function PipelineWidget() {
  const items = [
    { client: "Acme Co.",         amt: 12500, conf: "confirmed",   when: "May 5",  pct: 100 },
    { client: "Northwind",        amt:  7800, conf: "confirmed",   when: "May 12", pct: 100 },
    { client: "Globex",           amt:  9200, conf: "likely",      when: "May 22", pct: 75  },
    { client: "Initech",          amt:  4400, conf: "likely",      when: "Jun 1",  pct: 70  },
    { client: "Hooli (proposal)", amt: 18000, conf: "speculative", when: "Jun 15", pct: 35  },
  ];
  const colors = { confirmed:"var(--green-600)", likely:"#e8b53b", speculative:"#3a4068" };
  const weighted = items.reduce((s,it) => s + it.amt * it.pct/100, 0);
  return (
    <div className="fw-pipeline">
      <div className="fw-pipe-head">
        <div>
          <div className="metric-label">Income pipeline · 60 days</div>
          <div className="fw-pipe-total">
            <CountUp to={Math.round(weighted)} prefix="$"/>
            <span className="metric-sub" style={{marginLeft:8, fontWeight:400}}>weighted by confidence</span>
          </div>
        </div>
        <div className="fw-pipe-conf">
          <span><i style={{background:colors.confirmed}}/>Confirmed</span>
          <span><i style={{background:colors.likely}}/>Likely</span>
          <span><i style={{background:colors.speculative}}/>Speculative</span>
        </div>
      </div>
      <div className="fw-pipe-list">
        {items.map((it,i) => (
          <div key={i} className="fw-pipe-row">
            <div className="fw-pipe-client">{it.client}</div>
            <div className="fw-pipe-amt">${it.amt.toLocaleString()}</div>
            <div className="fw-pipe-bar">
              <div className="fw-pipe-fill" style={{width: it.pct+"%", background: colors[it.conf]}}/>
            </div>
            <div className="fw-pipe-when">{it.when}</div>
            <span className="fw-pipe-pill" style={{background:colors[it.conf]+"22", color:colors[it.conf]}}>{it.conf}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* =========================================================
   Scenario planner — best/expected/worst
   ========================================================= */
function ScenarioPlanner() {
  const [scn, setScn] = useFW("expected");
  const W = 540, H = 180, P = 24;
  const data = {
    best:     [22,28,33,38,44,52,60,68,77,86,96,108],
    expected: [22,24,26,28,30,33,36,38,41,44,47,50],
    worst:    [22,21,19,18,16,14,11, 8, 5, 1,-3,-7],
  };
  const all = [...data.best, ...data.expected, ...data.worst];
  const min = Math.min(...all, 0), max = Math.max(...all);
  const x = i => P + i * ((W-P*2)/(data.expected.length-1));
  const y = v => H - P - ((v - min)/(max-min)) * (H - P*2);
  const path = (arr) => arr.map((v,i)=>`${i===0?"M":"L"} ${x(i)} ${y(v)}`).join(" ");
  const colors = { best:"var(--green-500)", expected:"var(--charcoal-800)", worst:"#d44a4a" };
  return (
    <div className="fw-scenarios">
      <div className="fw-scn-head">
        <div className="metric-label">Cashflow scenarios · 12 mo</div>
        <div className="fw-scn-tabs">
          {["best","expected","worst"].map(s => (
            <button key={s} className={"fw-scn-tab " + (scn===s ? "active":"")} onClick={()=>setScn(s)}>
              <span style={{background:colors[s]}}/>{s}
            </button>
          ))}
        </div>
      </div>
      <svg viewBox={`0 0 ${W} ${H}`} className="fw-scn-svg">
        <line x1={P} x2={W-P} y1={y(0)} y2={y(0)} stroke="var(--gray-200)" strokeDasharray="2 3"/>
        <text x={W-P-2} y={y(0)-4} textAnchor="end" fontSize="9" fill="var(--charcoal-500)">$0</text>
        {["best","expected","worst"].map(s => (
          <path key={s} d={path(data[s])}
            fill="none"
            stroke={colors[s]}
            strokeWidth={scn===s ? 2.6 : 1.4}
            opacity={scn===s ? 1 : 0.25}
            strokeLinecap="round" strokeLinejoin="round"
            style={{transition:"all .4s"}}/>
        ))}
        {data[scn].map((v,i) => i % 3 === 0 && (
          <circle key={i} cx={x(i)} cy={y(v)} r="3" fill="#fff" stroke={colors[scn]} strokeWidth="2"/>
        ))}
      </svg>
      <div className="fw-scn-meta">
        <div>End balance: <strong style={{color:colors[scn]}}>${data[scn][data[scn].length-1]}K</strong></div>
        <div>Min point: <strong>${Math.min(...data[scn])}K</strong></div>
        <div>Reserve floor breached: <strong>{Math.min(...data[scn]) < 5 ? "Yes — buffer needed" : "No"}</strong></div>
      </div>
    </div>
  );
}

/* =========================================================
   Tax reserve auto-fill ladder — visualizes %-set-aside
   ========================================================= */
function TaxLadder() {
  const [pct, setPct] = useFW(28);
  const events = [
    { src: "Acme Co.",   amt: 5400, date: "Apr 3"  },
    { src: "Northwind",  amt: 3200, date: "Apr 11" },
    { src: "Retainer",   amt: 4000, date: "Apr 15" },
    { src: "Project X",  amt: 6800, date: "Apr 22" },
  ];
  const total = events.reduce((s,e) => s + e.amt, 0);
  const reserved = total * pct/100;
  return (
    <div className="fw-tax">
      <div className="fw-tax-head">
        <div>
          <div className="metric-label">Tax reserve auto-fill</div>
          <div className="fw-tax-rate">{pct}% of every deposit</div>
        </div>
        <div className="fw-tax-total">
          <CountUp to={Math.round(reserved)} prefix="$"/>
          <span className="metric-sub" style={{marginLeft:8, fontWeight:400}}>reserved this month</span>
        </div>
      </div>
      <input type="range" min="15" max="40" value={pct} onChange={e=>setPct(+e.target.value)} className="fw-range"/>
      <div className="fw-tax-events">
        {events.map((e,i) => (
          <div key={i} className="fw-tax-event">
            <div className="fw-tax-when">{e.date}</div>
            <div className="fw-tax-src">{e.src}</div>
            <div className="fw-tax-amt">${e.amt.toLocaleString()}</div>
            <div className="fw-tax-arrow">→</div>
            <div className="fw-tax-reserve">${Math.round(e.amt*pct/100).toLocaleString()}</div>
            <div className="fw-tax-bar">
              <div style={{width:pct+"%"}}></div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { LiveTicker, AllocatorWidget, KPIStrip, IncomeStreamsChart, PipelineWidget, ScenarioPlanner, TaxLadder });
