'use client'

import { useEffect, useState } from 'react'
import type { ReactNode } from 'react'
import { getMacroSnapshot, type MacroSnapshot } from '@/lib/api'
import { swrFetch } from '@/lib/cache'
import InfoTip from '@/components/ui/InfoTip'

function fmtUsd(n: number | null | undefined, { compact = false } = {}): string {
  if (n == null || isNaN(n)) return '—'
  const abs = Math.abs(n)
  if (compact) {
    if (abs >= 1e9) return `${(n / 1e9).toFixed(2)}B`
    if (abs >= 1e6) return `${(n / 1e6).toFixed(1)}M`
    if (abs >= 1e3) return `${(n / 1e3).toFixed(0)}K`
    return n.toFixed(0)
  }
  return n.toLocaleString('en-US', { maximumFractionDigits: 2 })
}

function fmtSignedUsd(n: number | null | undefined): string {
  if (n == null || isNaN(n)) return '—'
  const compact = fmtUsd(Math.abs(n), { compact: true })
  return (n >= 0 ? '+$' : '-$') + compact
}

function fmtPct(n: number | null | undefined, digits = 2): string {
  if (n == null || isNaN(n)) return '—'
  return n.toFixed(digits) + '%'
}

type Tone = 'up' | 'down' | 'neutral'

function toneAhr(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v < 0.45) return 'up'
  if (v > 1.2) return 'down'
  return 'neutral'
}
function toneAltseason(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v >= 75) return 'up'
  if (v <= 25) return 'down'
  return 'neutral'
}
function toneFearGreed(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v <= 25) return 'up'
  if (v >= 75) return 'down'
  return 'neutral'
}
function toneEtfFlow(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v > 50_000_000) return 'up'
  if (v < -50_000_000) return 'down'
  return 'neutral'
}
function toneBtcDominance(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v >= 60 || v <= 40) return 'down'
  return 'neutral'
}
function toneEthBtc(v: number | null): Tone {
  if (v == null) return 'neutral'
  if (v >= 0.04) return 'up'
  if (v <= 0.025) return 'down'
  return 'neutral'
}

const REGIME_COLOR: Record<string, string> = {
  BULL: 'var(--up)',
  BULLISH: 'var(--up)',
  NEUTRAL: 'var(--ink-3)',
  BEARISH: 'var(--down)',
  BEAR: 'var(--down)',
}

/**
 * Single "Open chart" button per card. Was two (Data source + Chart) — users
 * couldn't tell which to click and the dual-link group split attention.
 * Defaults to a CoinGlass page; when CoinGlass doesn't host the indicator
 * (Pi Cycle Bottom, Stablecoin Supply), we fall back to the canonical site.
 */
function SourceButton({
  href,
  children,
}: {
  href: string
  children: ReactNode
}) {
  return (
    <a
      href={href}
      target="_blank"
      rel="noreferrer"
      className="macro-action-btn chart"
    >
      <span className="macro-action-copy">
        <span className="macro-action-kicker">Open chart</span>
        <span className="macro-action-label">{children}</span>
      </span>
      <span className="macro-action-arrow" aria-hidden="true">↗</span>
    </a>
  )
}

function ThresholdChip({
  tone = 'neutral',
  active = false,
  children,
}: {
  tone?: Tone
  active?: boolean
  children: ReactNode
}) {
  const cls = `macro-threshold-chip ${tone}${active ? ' active' : ''}`
  return <span className={cls}>{children}</span>
}

function MetricCard({
  rank,
  label,
  value,
  tone = 'neutral',
  hint,
  summary,
  thresholds,
  activeIndex,
  chartHref,
  chartLabel = 'CoinGlass',
  hero = false,
}: {
  rank: number
  label: string
  value: string
  tone?: Tone
  /** What the indicator IS, one sentence. Do NOT enumerate threshold bands
   *  here — the chips below each card already list them. */
  hint: string
  summary: string
  thresholds: Array<{ label: string; tone?: Tone }>
  /** Index into `thresholds` of the band the current value falls into.
   *  Renders that chip with the .active class — full opacity + highlight. */
  activeIndex?: number
  /** URL of the canonical chart page (usually CoinGlass). One button only —
   *  the dual "Data source + Chart" pattern confused users about which to click. */
  chartHref: string
  chartLabel?: string
  /** Horizontal headline layout for a single full-width card (Valuation).
   *  The stacked layout stretched across the panel left a dead middle. */
  hero?: boolean
}) {
  const head = (
    <div className="macro-metric-head">
      <div className="macro-metric-title">
        <span className="macro-rank">{String(rank).padStart(2, '0')}</span>
        <span>{label}</span>
        <InfoTip text={hint} placement="top" width={280} />
      </div>
      <div className="macro-metric-value">{value}</div>
    </div>
  )
  const chips = (
    <div className="macro-thresholds">
      {thresholds.map((item, i) => (
        <ThresholdChip key={item.label} tone={item.tone} active={i === activeIndex}>
          {item.label}
        </ThresholdChip>
      ))}
    </div>
  )
  const action = (
    <div className="macro-actions">
      <SourceButton href={chartHref}>{chartLabel}</SourceButton>
    </div>
  )

  if (hero) {
    return (
      <article className={`macro-metric-card tone-${tone} hero`}>
        {head}
        <div className="macro-hero-body">
          <div className="macro-summary">{summary}</div>
          {chips}
        </div>
        {action}
      </article>
    )
  }

  return (
    <article className={`macro-metric-card tone-${tone}`}>
      {head}
      <div className="macro-summary">{summary}</div>
      {chips}
      {action}
    </article>
  )
}

function GuideCard({
  title,
  summary,
  thresholds,
  chartHref,
  chartLabel = 'CoinGlass',
}: {
  title: string
  summary: string
  thresholds: Array<{ label: string; tone?: Tone }>
  chartHref: string
  chartLabel?: string
}) {
  return (
    <article className="macro-guide-card">
      <div className="macro-guide-title">{title}</div>
      <div className="macro-summary">{summary}</div>
      <div className="macro-thresholds">
        {thresholds.map((item) => (
          <ThresholdChip key={item.label} tone={item.tone}>
            {item.label}
          </ThresholdChip>
        ))}
      </div>
      <div className="macro-actions">
        <SourceButton href={chartHref}>{chartLabel}</SourceButton>
      </div>
    </article>
  )
}

function Section({
  title,
  children,
  variant,
}: {
  title: string
  children: ReactNode
  /** "reference" tones the section down + adds a 📐 icon so users see at a
   *  glance that the cards inside are explainers, not live data. */
  variant?: 'reference'
}) {
  return (
    <section className={`macro-section${variant ? ' ' + variant : ''}`}>
      <div className="macro-section-title">{title}</div>
      {children}
    </section>
  )
}

export default function MacroPanel() {
  const [snap, setSnap] = useState<MacroSnapshot | null>(null)
  const [err, setErr] = useState('')

  useEffect(() => {
    let alive = true
    function load() {
      swrFetch(
        'macro-snapshot',
        10 * 60_000,
        () => getMacroSnapshot(),
        (fresh) => { if (alive) setSnap(fresh) },
      )
        .then((s) => { if (alive) { setSnap(s); setErr('') } })
        .catch((e) => { if (alive) setErr(e instanceof Error ? e.message : 'load failed') })
    }
    load()
    const id = setInterval(load, 10 * 60_000)
    return () => { alive = false; clearInterval(id) }
  }, [])

  if (err) {
    return (
      <div className="card" style={{ padding: 14, fontSize: 12, color: 'var(--down)' }}>
        Couldn&apos;t load macro indicators — {err}
      </div>
    )
  }
  if (!snap) {
    return (
      <div className="skeleton-card">
        <div className="skeleton sk-line sk-w-3q" />
        <div className="skeleton sk-line sk-w-half" />
        <div className="skeleton sk-line sk-w-full" />
      </div>
    )
  }
  if (!snap.ok || !snap.indicators) {
    return (
      <div className="card" style={{ padding: 14, fontSize: 12, color: 'var(--ink-3)' }}>
        Macro snapshot not available yet — {snap.error ?? 'cron has not run'}.
      </div>
    )
  }

  const ind = snap.indicators

  const ahrSay =
    ind.ahr999 == null ? 'No data yet.'
    : ind.ahr999 < 0.45 ? 'Deep-value zone. Historically this is where macro accumulation starts to make sense.'
    : ind.ahr999 > 1.2 ? 'Expensive regime. This is no longer a bottom setup.'
    : ind.ahr999 < 0.75 ? 'Reasonable value. Closer to cheap than to overheated.'
    : 'Neutral-to-rich. No strong valuation edge from this metric alone.'

  const altSay =
    ind.altcoin_season_index == null ? 'No data yet.'
    : ind.altcoin_season_index >= 75 ? 'Altseason conditions. Broad risk appetite is favoring alts over BTC.'
    : ind.altcoin_season_index >= 60 ? 'Alt strength is building, but it is not a full altseason yet.'
    : ind.altcoin_season_index >= 40 ? 'Mixed tape. Neither BTC nor alts have a decisive lead.'
    : ind.altcoin_season_index >= 25 ? 'BTC is leading. This is a more defensive market posture.'
    : 'Bitcoin season. Alts are broadly lagging BTC.'

  const fgSay =
    ind.fear_greed == null ? 'No data yet.'
    : ind.fear_greed <= 20 ? 'Extreme fear. Contrarian bottom-hunting conditions.'
    : ind.fear_greed <= 40 ? 'Fear is present, but not yet a full washout.'
    : ind.fear_greed <= 60 ? 'Neutral sentiment. Little edge from crowd psychology here.'
    : ind.fear_greed <= 80 ? 'Greed is building. Be selective about adding exposure.'
    : 'Extreme greed. Historically a poor place to chase upside.'

  const domSay =
    ind.btc_dominance_pct == null ? 'No data yet.'
    : ind.btc_dominance_pct >= 65 ? 'Capital is crowding back into BTC. That usually reads as caution.'
    : ind.btc_dominance_pct >= 55 ? 'BTC still leads the market. Risk appetite is present, but selective.'
    : ind.btc_dominance_pct >= 45 ? 'Balanced regime. No strong breadth message from dominance.'
    : ind.btc_dominance_pct >= 35 ? 'Alt participation is improving. Risk appetite is broadening.'
    : 'Dominance is very low. That often shows late-cycle froth.'

  const ebrSay =
    ind.eth_btc_ratio == null ? 'No data yet.'
    : ind.eth_btc_ratio >= 0.05 ? 'ETH leadership is strong. This usually maps to a cleaner risk-on regime.'
    : ind.eth_btc_ratio >= 0.04 ? 'ETH is waking up versus BTC. Useful confirmation for broader crypto risk appetite.'
    : ind.eth_btc_ratio >= 0.03 ? 'Range-bound. ETH/BTC is not giving a decisive leadership signal.'
    : ind.eth_btc_ratio >= 0.025 ? 'ETH is lagging, which usually means BTC remains the safer bid.'
    : 'ETH is weak versus BTC. This is a defensive backdrop.'

  const stabSay = ind.stablecoin_supply_usd == null
    ? 'No data yet.'
    : 'This is a liquidity gauge, not a hard trigger. Watch the direction of supply over time.'

  const etfSay = ind.etf_flow_net_usd_1d == null ? 'No data yet.' : (() => {
    const v = ind.etf_flow_net_usd_1d ?? 0
    if (v >= 500_000_000) return 'Huge ETF inflow day. Institutions are pressing the bid.'
    if (v >= 200_000_000) return 'Strong inflow day. Institutional demand is clearly supportive.'
    if (v >= 50_000_000) return 'Positive day, but not a major outlier.'
    if (v > -50_000_000) return 'Roughly flat. No strong institutional message.'
    if (v > -200_000_000) return 'Moderate outflow day. Some distribution, but not panic.'
    if (v > -500_000_000) return 'Heavy outflows. Institutions are leaning defensive.'
    return 'Very large outflows. This is a meaningful risk-off signal.'
  })()

  const oiSay = ind.btc_open_interest_usd == null
    ? 'No data yet.'
    : 'Use this with price, not by itself. Rising OI confirms commitment; falling OI shows deleveraging.'

  // ── Active threshold band per indicator ─────────────────────────────────
  // Each function returns the index into the indicator's `thresholds` array
  // that the CURRENT value falls into. Renders that chip with the .active
  // CSS class so it stands out from the muted siblings.
  // Indexes MUST stay in lock-step with the threshold array order below.
  const ahrActive = ind.ahr999 == null ? -1
    : ind.ahr999 < 0.45 ? 0
    : ind.ahr999 < 0.75 ? 1
    : ind.ahr999 <= 1.2 ? 2
    : 3
  const altActive = ind.altcoin_season_index == null ? -1
    : ind.altcoin_season_index < 25 ? 0
    : ind.altcoin_season_index < 60 ? 1
    : ind.altcoin_season_index < 75 ? 2
    : 3
  const fgActive = ind.fear_greed == null ? -1
    : ind.fear_greed < 25 ? 0
    : ind.fear_greed < 45 ? 1
    : ind.fear_greed < 60 ? 2
    : ind.fear_greed < 75 ? 3
    : 4
  const domActive = ind.btc_dominance_pct == null ? -1
    : ind.btc_dominance_pct < 45 ? 0
    : ind.btc_dominance_pct < 55 ? 1
    : ind.btc_dominance_pct < 65 ? 2
    : 3
  const ebrActive = ind.eth_btc_ratio == null ? -1
    : ind.eth_btc_ratio < 0.025 ? 0
    : ind.eth_btc_ratio < 0.04  ? 1
    : 2
  const etfActive = ind.etf_flow_net_usd_1d == null ? -1
    : ind.etf_flow_net_usd_1d >  200_000_000 ? 0
    : ind.etf_flow_net_usd_1d < -200_000_000 ? 2
    : 1
  const stabActive = ind.stablecoin_supply_usd == null ? -1 : 1  // we can't infer trend → land mid

  const compositeColor =
    snap.composite_score == null ? 'var(--ink-3)'
    : snap.composite_score > 3 ? 'var(--up)'
    : snap.composite_score < -3 ? 'var(--down)'
    : 'var(--ink-3)'

  const compositePct =
    snap.composite_score == null ? 50
    : Math.max(0, Math.min(100, (snap.composite_score + 100) / 2))

  const trackGradient =
    'linear-gradient(to right, ' +
    'color-mix(in oklab, var(--down) 70%, transparent) 0%, ' +
    'color-mix(in oklab, var(--down) 25%, transparent) 35%, ' +
    'var(--bg-sunk) 50%, ' +
    'color-mix(in oklab, var(--up) 25%, transparent) 65%, ' +
    'color-mix(in oklab, var(--up) 70%, transparent) 100%)'

  return (
    <div className="card macro-panel">
      <div className="macro-panel-head">
        <div>
          <div className="macro-panel-title">
            <span className="macro-panel-dot" />
            Macro indicators
          </div>
          <div className="macro-panel-subtitle">
            Daily snapshot for BTC macro context. Designed for scanning first, details second.
          </div>
        </div>
        <div className="macro-panel-meta">
          <div>{snap.date}</div>
          <div>free public sources</div>
        </div>
      </div>

      <Section title="Valuation">
        <div className="macro-grid one">
          <MetricCard
            hero
            rank={1}
            label="AHR999"
            value={ind.ahr999?.toFixed(4) ?? '—'}
            tone={toneAhr(ind.ahr999)}
            hint="BTC valuation index: price vs 200-day geometric mean × price vs fitted long-run growth curve. Lower = cheaper."
            summary={ahrSay}
            activeIndex={ahrActive}
            thresholds={[
              { label: '< 0.45 buy zone', tone: 'up' },
              { label: '0.45–0.75 fair value', tone: 'neutral' },
              { label: '0.75–1.2 no edge', tone: 'neutral' },
              { label: '> 1.2 expensive', tone: 'down' },
            ]}
            chartHref="https://www.coinglass.com/en/pro/i/ahr999"
            chartLabel="CoinGlass"
          />
        </div>
      </Section>

      <Section title="Bottom trigger reference" variant="reference">
        <div className="macro-grid two">
          <GuideCard
            title="200-week Moving Average"
            summary="A structural support check. In this system, price near the 200WMA is one of the three bottom votes."
            thresholds={[
              { label: '≤ 1.05× 200WMA = vote ON', tone: 'up' },
              { label: 'Below 200WMA = strongest value zone', tone: 'up' },
              { label: '1.05×–1.20× above = recovering', tone: 'neutral' },
              { label: 'Far above = no bottom vote', tone: 'down' },
            ]}
            chartHref="https://www.coinglass.com/pro/i/200WMA"
            chartLabel="CoinGlass"
          />
          <GuideCard
            title="Pi Cycle Bottom"
            summary="A binary bottom condition. It is either confirmed or not confirmed; there is no graded middle reading in the live code."
            thresholds={[
              { label: '150EMA ≤ 471SMA × 0.745 = vote ON', tone: 'up' },
              { label: '150EMA above line = not confirmed', tone: 'down' },
            ]}
            // CoinGlass only hosts Pi Cycle TOP; for Pi Cycle BOTTOM the
            // canonical chart lives on LookIntoBitcoin.
            chartHref="https://www.lookintobitcoin.com/charts/pi-cycle-bottom-indicator/"
            chartLabel="LookIntoBitcoin"
          />
        </div>
      </Section>

      <Section title="Market structure">
        <div className="macro-grid two">
          <MetricCard
            rank={2}
            label="Altcoin Season"
            value={ind.altcoin_season_index == null ? '—' : ind.altcoin_season_index.toFixed(0) + ' / 100'}
            tone={toneAltseason(ind.altcoin_season_index)}
            hint="% of top-50 alts that beat BTC over the last 90 days (blockchaincenter.net formula). Higher = broader alt strength."
            summary={altSay}
            activeIndex={altActive}
            thresholds={[
              { label: '< 25 Bitcoin season', tone: 'down' },
              { label: '25–60 mixed', tone: 'neutral' },
              { label: '60–75 alt strength', tone: 'up' },
              { label: '≥ 75 altseason', tone: 'up' },
            ]}
            chartHref="https://www.blockchaincenter.net/altcoin-season-index/"
            chartLabel="BlockchainCenter"
          />
          <MetricCard
            rank={3}
            label="BTC Dominance"
            value={fmtPct(ind.btc_dominance_pct)}
            tone={toneBtcDominance(ind.btc_dominance_pct)}
            hint="BTC's share of total crypto market cap. High dominance = defensive, capital hiding in BTC; low = alt rotation."
            summary={domSay}
            activeIndex={domActive}
            thresholds={[
              { label: '< 45% alt rotation', tone: 'up' },
              { label: '45–55% balanced', tone: 'neutral' },
              { label: '55–65% BTC-led', tone: 'neutral' },
              { label: '> 65% safety trade', tone: 'down' },
            ]}
            chartHref="https://www.coinglass.com/pro/i/bitcoin-dominance"
            chartLabel="CoinGlass"
          />
          <MetricCard
            rank={4}
            label="ETH / BTC"
            value={ind.eth_btc_ratio == null ? '—' : ind.eth_btc_ratio.toFixed(5)}
            tone={toneEthBtc(ind.eth_btc_ratio)}
            hint="Relative strength of ETH vs BTC — a proxy for broader crypto risk appetite."
            summary={ebrSay}
            activeIndex={ebrActive}
            thresholds={[
              { label: '< 0.025 defensive', tone: 'down' },
              { label: '0.025–0.04 range', tone: 'neutral' },
              { label: '> 0.04 ETH leadership', tone: 'up' },
            ]}
            chartHref="https://www.coinglass.com/currencies/ETHBTC"
            chartLabel="CoinGlass"
          />
        </div>
      </Section>

      <Section title="Sentiment & flows">
        <div className="macro-grid two">
          <MetricCard
            rank={5}
            label="Fear & Greed"
            value={ind.fear_greed == null ? '—' : String(ind.fear_greed)}
            tone={toneFearGreed(ind.fear_greed)}
            hint="Sentiment composite from alternative.me. CONTRARIAN read — extreme fear is bullish, extreme greed is bearish."
            summary={fgSay}
            activeIndex={fgActive}
            thresholds={[
              { label: '< 25 → BUY (extreme fear)',  tone: 'up' },
              { label: '25–45 fear',                 tone: 'neutral' },
              { label: '45–60 neutral',              tone: 'neutral' },
              { label: '60–75 greed',                tone: 'neutral' },
              { label: '> 75 → SELL (extreme greed)', tone: 'down' },
            ]}
            chartHref="https://www.coinglass.com/pro/i/FearGreedIndex?s=09"
            chartLabel="CoinGlass"
          />
          <MetricCard
            rank={6}
            label="Stablecoin Supply"
            value={ind.stablecoin_supply_usd == null ? '—' : '$' + fmtUsd(ind.stablecoin_supply_usd, { compact: true })}
            summary={stabSay}
            hint="Sum of all USDT + USDC + DAI + others in circulation. Rising = dry powder accumulating; falling = capital exiting crypto."
            activeIndex={stabActive}
            thresholds={[
              { label: 'Rising = liquidity building', tone: 'up' },
              { label: 'Flat = neutral', tone: 'neutral' },
              { label: 'Falling = capital leaving', tone: 'down' },
            ]}
            // CoinGlass doesn't expose an all-issuer stablecoin supply view
            // cleanly; DeFiLlama is the canonical aggregator we pull from.
            chartHref="https://defillama.com/stablecoins"
            chartLabel="DeFiLlama"
          />
          <MetricCard
            rank={7}
            label="ETF Net Flow (1d)"
            value={fmtSignedUsd(ind.etf_flow_net_usd_1d)}
            tone={toneEtfFlow(ind.etf_flow_net_usd_1d)}
            hint="Yesterday's total net flow into/out of US spot BTC ETFs — a direct read on institutional demand."
            summary={etfSay}
            activeIndex={etfActive}
            thresholds={[
              { label: '> +$200M strong bid', tone: 'up' },
              { label: '±$50M noise band', tone: 'neutral' },
              { label: '< −$200M heavy outflow', tone: 'down' },
            ]}
            chartHref="https://www.coinglass.com/etf"
          />
          <MetricCard
            rank={8}
            label="BTC Open Interest"
            value={ind.btc_open_interest_usd == null ? '—' : '$' + fmtUsd(ind.btc_open_interest_usd, { compact: true })}
            summary={oiSay}
            hint="Total notional in BTC futures. No universal absolute threshold: use OI with price. Rising OI + rising price = trend confirmation; rising OI + falling price = trapped longs."
            thresholds={[
              { label: 'OI up + price up = confirmation', tone: 'up' },
              { label: 'OI up + price down = stress', tone: 'down' },
              { label: 'OI down after flush = reset', tone: 'neutral' },
            ]}
            chartHref="https://www.tradingview.com/symbols/BTC_OI/"
            chartLabel="TradingView"
          />
        </div>
      </Section>

      <div className="macro-composite">
        <div className="macro-composite-head">
          <div>
            <div className="macro-composite-label">Composite read</div>
            <div className="macro-panel-subtitle">
              Advisory blend of the metrics above. Useful for context, not for blind execution.
            </div>
          </div>
          <div className="macro-composite-right">
            <span className="macro-composite-value" style={{ color: compositeColor }}>
              {snap.composite_score == null
                ? '—'
                : (snap.composite_score > 0 ? '+' : '') + snap.composite_score.toFixed(1)}
            </span>
            {snap.regime_label ? (
              <span
                className="macro-regime-pill"
                style={{
                  color: REGIME_COLOR[snap.regime_label] || 'var(--ink-3)',
                  borderColor: `color-mix(in oklab, ${REGIME_COLOR[snap.regime_label] || 'var(--ink-3)'} 32%, transparent)`,
                  background: `color-mix(in oklab, ${REGIME_COLOR[snap.regime_label] || 'var(--ink-3)'} 12%, transparent)`,
                }}
              >
                {snap.regime_label}
              </span>
            ) : null}
          </div>
        </div>

        <div className="macro-composite-track" style={{ background: trackGradient }}>
          {snap.composite_score != null ? (
            <div
              // Keying by score forces a remount → the @keyframes pulse on
              // .macro-composite-needle re-fires every time the score moves.
              key={snap.composite_score}
              className="macro-composite-needle"
              style={{
                left: `calc(${compositePct}% - 10px)`,
                borderColor: compositeColor,
                color: compositeColor,
              }}
            />
          ) : null}
        </div>
        <div className="macro-composite-scale">
          {/* .word spans are hidden on screens ≤420px so the scale becomes
              just "-100", "0", "+100" — fits comfortably on any phone. */}
          <span>−100 <span className="word">bear</span></span>
          <span>0 <span className="word">neutral</span></span>
          <span>+100 <span className="word">bull</span></span>
        </div>
      </div>
    </div>
  )
}
