/* global React, AC_CONFIG, apiGet, apiPost, krw, Sparkline */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// =============== STATE HOOK — live snapshot polling ===============
function useBotState() {
  const [snapshot, setSnapshot] = useState(null);
  const [error, setError] = useState(null);
  const lastFetchRef = useRef(0);

  const refresh = useCallback(async () => {
    try {
      const data = await apiGet(AC_CONFIG.snapshotUrl);
      window.TICKERS = data.tickers || [];
      window.STRATEGIES = data.strategies || [];
      window.ORDERS_SEED = data.orders || [];
      window.AUDIT_SEED = data.audit || [];
      window.WEBHOOKS_SEED = data.webhooks || [];
      window.PORTFOLIO = data.portfolio || [];
      lastFetchRef.current = Date.now();
      setSnapshot(data);
      setError(null);
    } catch (err) {
      setError(err.message || String(err));
    }
  }, []);

  useEffect(() => {
    refresh();
    const id = setInterval(refresh, AC_CONFIG.pollIntervalMs);
    return () => clearInterval(id);
  }, [refresh]);

  // ===== mutators (POST + immediate refresh) =====
  const setRunning = useCallback(async (next) => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/${next ? 'start' : 'stop'}`, {});
      refresh();
    } catch (err) { setError(err.message || String(err)); }
  }, [refresh]);

  const setMode = useCallback(async (next) => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/mode`, { mode: next });
      refresh();
    } catch (err) { setError(err.message || String(err)); }
  }, [refresh]);

  const setKillSwitch = useCallback(async (next) => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/kill-switch`, { value: !!next });
      refresh();
    } catch (err) { setError(err.message || String(err)); }
  }, [refresh]);

  const reload = useCallback(async () => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/reload`, {});
      refresh();
    } catch (err) { setError(err.message || String(err)); }
  }, [refresh]);

  const setActiveStrat = useCallback(async (id) => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/strategy`, { strategy: id });
      refresh();
    } catch (err) { setError(err.message || String(err)); }
  }, [refresh]);

  const setPortfolio = useCallback(async (tickers) => {
    try {
      await apiPost(`${AC_CONFIG.controlUrl}/portfolio`, { tickers });
      await refresh();
      return null;
    } catch (err) {
      const msg = err.message || String(err);
      setError(msg);
      return msg;
    }
  }, [refresh]);

  // 빈 스냅샷 fallback (최초 폴 직전 첫 렌더)
  const empty = useMemo(() => ({
    running: false, mode: 'paper', is_live: false, live_view: false, kill_switch: false,
    tickers: [], portfolio: [], watchlist: [],
    orders: [], audit: [], webhooks: [], equity: [], strategies: [],
    slots_used: 0, slots_max: 3,
    krw_balance: 0, position_value: 0, position_cost: 0,
    total_cost_krw: 0, total_value_krw: 0, total_equity: 0,
    today_pnl: 0, today_pnl_pct: 0, cum_pnl: 0, cum_pnl_pct: 0,
    daily_loss_limit_krw: 0, daily_loss_limit_pct: 0, loss_used_pct: 0,
    win_rate_30d: 0, sharpe_30d: 0,
    active_strategy: '', tick_count: 0,
    risk: {}, schedule: {},
  }), []);
  const data = snapshot || empty;

  return {
    error, refresh,
    running: !!data.running,
    mode: data.mode || 'paper',
    isLive: !!data.is_live,
    liveView: !!data.live_view,
    killSwitch: !!data.kill_switch,
    tickers: data.tickers || [],
    portfolio: data.portfolio || [],
    watchlist: data.watchlist || [],
    orders: data.orders || [],
    audit: data.audit || [],
    webhooks: data.webhooks || [],
    equity: data.equity || [],
    strategies: data.strategies || [],
    activeStrat: data.active_strategy || '',
    tickCount: data.tick_count || 0,
    positions: (data.tickers || []).filter(t => (t.qty || 0) > 0),
    slotsUsed: data.slots_used || 0,
    slotsMax: data.slots_max || 3,
    krwBalance: data.krw_balance || 0,
    positionValue: data.position_value || 0,
    positionCost: data.position_cost || 0,
    totalCostKrw: data.total_cost_krw || 0,
    totalValueKrw: data.total_value_krw || 0,
    totalEquity: data.total_equity || 0,
    todayPnl: data.today_pnl || 0,
    todayPnlPct: data.today_pnl_pct || 0,
    cumPnl: data.cum_pnl || 0,
    cumPnlPct: data.cum_pnl_pct || 0,
    dailyLossLimit: data.daily_loss_limit_krw || 0,
    dailyLossLimitPct: data.daily_loss_limit_pct || 0,
    lossUsedPct: data.loss_used_pct || 0,
    winRate30d: data.win_rate_30d || 0,
    sharpe30d: data.sharpe_30d || 0,
    risk: data.risk || {},
    schedule: data.schedule || {},
    setRunning, setMode, setKillSwitch, reload, setActiveStrat, setPortfolio,
  };
}

// =============== TOP BAR ===============
function TopBar({ page, setPage, mode, running, killSwitch }) {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []);
  const navItems = [
    { id: 'dash',    label: '대시보드', n: 'F1' },
    { id: 'strat',   label: '전략',     n: 'F2' },
    { id: 'pos',     label: '포지션',   n: 'F3' },
    { id: 'orders',  label: '주문',     n: 'F4' },
    { id: 'webhooks', label: '웹훅',    n: 'F5' },
    { id: 'risk',    label: '리스크',   n: 'F6' },
    { id: 'audit',   label: '감사',     n: 'F7' },
    { id: 'settings', label: '설정',     n: 'F8' },
  ];
  const t = now.toTimeString().slice(0, 8);
  const d = now.toISOString().slice(0, 10);
  return (
    <header className="topbar">
      <div className="topbar-brand">
        <span className="logo"></span>
        <span>AUTO_COIN</span>
        <span className="faint" style={{ fontWeight: 400, marginLeft: 4 }}>v{(window.AC_CONFIG && window.AC_CONFIG.version) || ''}</span>
      </div>
      <nav>
        {navItems.map(item => (
          <button key={item.id}
                  className={page === item.id ? 'active' : ''}
                  onClick={() => setPage(item.id)}>
            <span className="num">{item.n}</span>
            <span>{item.label}</span>
          </button>
        ))}
      </nav>
      <div className="topbar-right">
        <span className="session-pill">
          <span className={`dot ${running ? 'live' : 'mute'}`} />
          {running ? '스케줄 · 실행중' : '정지'}
        </span>
        <span className="session-pill" style={{
          color: mode === 'live' ? 'var(--down)' : 'var(--accent)',
          borderColor: mode === 'live' ? 'oklch(0.66 0.21 25 / 0.5)' : 'var(--accent-dim)',
        }}>
          <span className={`dot ${mode === 'live' ? 'down' : 'live'}`} />
          {mode === 'live' ? '실거래' : '페이퍼'}
        </span>
        {killSwitch && (
          <span className="session-pill" style={{ color: 'var(--warn)', borderColor: 'oklch(0.80 0.15 80 / 0.5)' }}>
            <span className="dot warn" /> 킬스위치
          </span>
        )}
        <span className="clock"><span className="label">KST</span>{d} {t}</span>
      </div>
    </header>
  );
}

// =============== SIDE RAIL ===============
function SideRail(props) {
  const {
    running, setRunning, mode, setMode, killSwitch, setKillSwitch, reload,
    slotsUsed, slotsMax, krwBalance, positionValue, tickCount,
    activeStrat, strategies, schedule,
  } = props;
  const stratLabel = (strategies.find(s => s.id === activeStrat)?.code) || '—';
  const tickInterval = (schedule.tick_seconds ? `${schedule.tick_seconds}s` : '—');
  return (
    <aside className="rail">
      <div className="group">
        <h4>봇 제어</h4>
        <div className="seg" style={{ marginBottom: 8 }}>
          <button className={'paper ' + (mode === 'paper' ? 'on' : '')}
                  onClick={() => setMode('paper')}>페이퍼</button>
          <button className={'live ' + (mode === 'live' ? 'on' : '')}
                  onClick={() => {
                    if (mode !== 'live' && !confirm('실거래로 전환합니다. 실제 원화가 위험에 노출됩니다. 진행하시겠습니까?')) return;
                    setMode(mode === 'live' ? 'paper' : 'live');
                  }}>실거래</button>
        </div>
        <div className="btn-group">
          {running ? (
            <button className="btn danger sm" onClick={() => setRunning(false)}>정지</button>
          ) : (
            <button className="btn primary sm" onClick={() => setRunning(true)}>시작</button>
          )}
          <button className="btn ghost sm" onClick={() => reload()}>재로드</button>
        </div>
        <div style={{ marginTop: 6 }}>
          <button className={'btn full sm ' + (killSwitch ? 'warn' : 'ghost')}
                  onClick={() => setKillSwitch(!killSwitch)}>
            <span className={`dot ${killSwitch ? 'warn' : 'mute'}`} />
            킬스위치 {killSwitch ? 'ON' : 'OFF'}
          </button>
        </div>
      </div>

      <div className="group">
        <h4>상태</h4>
        <div className="row"><span className="k">슬롯</span><span className="v">{slotsUsed}/{slotsMax}</span></div>
        <div className="row"><span className="k">전략</span><span className="v accent-color">{stratLabel}</span></div>
        <div className="row"><span className="k">틱 주기</span><span className="v">{tickInterval}</span></div>
        <div className="row"><span className="k">오늘 틱</span><span className="v">{tickCount.toLocaleString()}</span></div>
      </div>

      <div className="group">
        <h4>지갑</h4>
        <div className="row"><span className="k">원화</span><span className="v">{krw(krwBalance)}</span></div>
        <div className="row"><span className="k">포지션 평가</span><span className="v">{krw(Math.round(positionValue))}</span></div>
        <div className="row"><span className="k">총 자산</span><span className="v accent-color">{krw(Math.round(krwBalance + positionValue))}</span></div>
      </div>

      <div className="group">
        <h4>스케줄</h4>
        <div className="row"><span className="k">강제 청산</span><span className="v">{schedule.exit_hh_mm || '—'}</span></div>
        <div className="row"><span className="k">리포트</span><span className="v">{schedule.report_hh_mm || '—'}</span></div>
        <div className="row"><span className="k">일일 리셋</span><span className="v">{schedule.reset_hh_mm || '—'}</span></div>
        <div className="row"><span className="k">시간대</span><span className="v">{schedule.tz || 'KST'}</span></div>
      </div>
    </aside>
  );
}

// =============== STATUS BAR (footer) ===============
function StatusBar({ tickCount, mode, running, error }) {
  return (
    <footer className="statusbar">
      <span className="seg"><span className={`dot ${running ? 'live' : 'mute'}`} /><span className="label">스케줄</span><span className="val">{running ? '실행중' : '정지'}</span></span>
      <span className="seg"><span className="label">모드</span><span className="val" style={{ color: mode === 'live' ? 'var(--down)' : 'var(--accent)' }}>{mode === 'live' ? '실거래' : '페이퍼'}</span></span>
      <span className="seg"><span className="label">틱</span><span className="val">{tickCount.toLocaleString()}</span></span>
      {error && (
        <span className="seg" style={{ color: 'var(--down)' }}>
          <span className="label">오류</span><span className="val">{error}</span>
        </span>
      )}
      <span className="seg right"><span className="label">F1</span><span className="val">대시</span><span className="label">·</span><span className="val">F2 전략</span><span className="label">·</span><span className="val">F5 리스크</span><span className="label">·</span><span className="val">⌃K 킬스위치</span></span>
    </footer>
  );
}

Object.assign(window, { useBotState, TopBar, SideRail, StatusBar });
