// ============================================================
// 共通UIコンポーネント(ダーク金融トレーダー系)
// ============================================================
const T = window.TOKENS;

// ─────────────────────────────────────────
// アイコン(ストローク型、細身)
// ─────────────────────────────────────────
const Icon = ({ name, size = 20, color = 'currentColor', stroke = 1.8 }) => {
  const paths = {
    home:    <path d="M3 10.5L12 3l9 7.5V20a1 1 0 01-1 1h-5v-7h-6v7H4a1 1 0 01-1-1v-9.5z" />,
    wallet:  <path d="M3 7a2 2 0 012-2h13a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V7zM3 10h18M16 14h2" />,
    cal:     <path d="M4 6a2 2 0 012-2h12a2 2 0 012 2v13a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM4 10h16M8 3v4M16 3v4" />,
    chart:   <path d="M4 20V10M10 20V4M16 20v-7M22 20H2" />,
    more:    <path d="M4 12h.01M12 12h.01M20 12h.01" />,
    settings:<path d="M12 15a3 3 0 100-6 3 3 0 000 6z M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z" />,
    plus:    <path d="M12 5v14M5 12h14" />,
    check:   <path d="M20 6L9 17l-5-5" />,
    chevR:   <path d="M9 6l6 6-6 6" />,
    chevL:   <path d="M15 6l-6 6 6 6" />,
    chevD:   <path d="M6 9l6 6 6-6" />,
    chevU:   <path d="M6 15l6-6 6 6" />,
    sync:    <path d="M21 12a9 9 0 01-15.5 6.3M3 12a9 9 0 0115.5-6.3M3 20v-5h5M21 4v5h-5" />,
    dot:     <circle cx="12" cy="12" r="4" fill={color} stroke="none" />,
    warn:    <path d="M12 3l10 18H2L12 3zM12 10v5M12 18h.01" />,
    info:    <path d="M12 22a10 10 0 100-20 10 10 0 000 20zM12 8v.01M11 12h1v5h1" />,
    close:   <path d="M18 6L6 18M6 6l12 12" />,
    copy:    <path d="M8 8h11v11H8zM5 5h11v3M5 5v11h3" />,
    download:<path d="M12 3v13M6 11l6 6 6-6M4 21h16" />,
    dl:      <path d="M12 3v13M6 11l6 6 6-6M4 21h16" />,
    ea:      <path d="M4 4h16v6H4zM4 14h16v6H4zM8 7h.01M8 17h.01" />,
    trash:   <path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" />,
    filter:  <path d="M3 5h18l-7 8v6l-4 2v-8L3 5z" />,
    search:  <path d="M11 19a8 8 0 100-16 8 8 0 000 16zM21 21l-4.35-4.35" />,
    external:<path d="M14 3h7v7M21 3l-9 9M19 14v6H4V5h6" />,
    zap:     <path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" />,
    shield:  <path d="M12 22s8-4 8-11V4l-8-2-8 2v7c0 7 8 11 8 11z" />,
    edit:    <path d="M12 20h9M16.5 3.5l4 4L7 21H3v-4L16.5 3.5z" />,
    tag:     <path d="M20 12l-8 8-9-9V3h8l9 9zM7 7h.01" />,
    minus:   <path d="M5 12h14" />,
    play:    <path d="M6 4l14 8-14 8V4z" />,
    tester:  <path d="M9 2h6v3l3 4v13H6V9l3-4V2zM9 12h6M9 16h6" />,
    key:     <path d="M15 7a4 4 0 11-4 4h-2v3H7v3H3v-4l6-6a4 4 0 016-0z" />,
    server:  <path d="M4 5h16v5H4zM4 14h16v5H4zM7 7.5h.01M7 16.5h.01" />,
    link:    <path d="M10 14a5 5 0 007 0l3-3a5 5 0 00-7-7l-1 1M14 10a5 5 0 00-7 0l-3 3a5 5 0 007 7l1-1" />,
    circle:  <circle cx="12" cy="12" r="10" fill="none" />,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, display: 'block' }}>
      {paths[name] || null}
    </svg>
  );
};

// ─────────────────────────────────────────
// ステータスドット
// ─────────────────────────────────────────
const StatusDot = ({ status = 'online', size = 8 }) => {
  const c = status === 'online' ? T.profit :
            status === 'stale'  ? T.warn :
            status === 'offline'? T.loss : T.fg3;
  return (
    <span style={{
      display: 'inline-block', width: size, height: size, borderRadius: 999,
      background: c, boxShadow: `0 0 0 3px ${c}20`,
    }} />
  );
};

// ─────────────────────────────────────────
// バッジ
// ─────────────────────────────────────────
const Badge = ({ children, tone = 'default', size = 'sm' }) => {
  const tones = {
    default: { bg: T.raised, fg: T.fg2, bd: T.line },
    profit:  { bg: T.profitBg, fg: T.profit, bd: 'rgba(34,197,94,0.25)' },
    loss:    { bg: T.lossBg, fg: T.loss, bd: 'rgba(244,63,94,0.25)' },
    info:    { bg: T.infoBg, fg: T.info, bd: 'rgba(59,130,246,0.25)' },
    warn:    { bg: T.warnBg, fg: T.warn, bd: 'rgba(245,158,11,0.25)' },
    mt4:     { bg: 'rgba(59,130,246,0.10)', fg: '#60A5FA', bd: 'rgba(59,130,246,0.25)' },
    mt5:     { bg: 'rgba(168,85,247,0.10)', fg: '#C084FC', bd: 'rgba(168,85,247,0.25)' },
  };
  const t = tones[tone] || tones.default;
  const pad = size === 'xs' ? '2px 6px' : '3px 8px';
  const fs = size === 'xs' ? 10 : 11;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: pad, borderRadius: 6, fontSize: fs, fontWeight: 600,
      background: t.bg, color: t.fg, border: `1px solid ${t.bd}`,
      letterSpacing: 0.2, lineHeight: 1, whiteSpace: 'nowrap',
      fontFamily: T.fontUi,
    }}>
      {children}
    </span>
  );
};

// ─────────────────────────────────────────
// 損益テキスト(色付き + 等幅)
// ─────────────────────────────────────────
const PnL = ({ value, size = 14, sign = true, compact = false, weight = 600, mono = true }) => {
  if (value === null || value === undefined) {
    return <span style={{ fontSize: size, color: T.fg3, fontFamily: mono ? T.fontMono : T.fontUi }}>—</span>;
  }
  const c = value > 0 ? T.profit : value < 0 ? T.loss : T.fg2;
  return (
    <span style={{
      color: c, fontSize: size, fontWeight: weight,
      fontFamily: mono ? T.fontMono : T.fontUi,
      fontVariantNumeric: 'tabular-nums',
      letterSpacing: -0.2,
    }}>
      {window.fmt.jpy(value, { sign, compact })}
    </span>
  );
};

// ─────────────────────────────────────────
// ピル型セグメントタブ(スワイプ対応)
// ─────────────────────────────────────────
const PillTabs = ({ options, value, onChange }) => {
  return (
    <div style={{
      display: 'flex', gap: 4, padding: 3,
      background: T.surface, border: `1px solid ${T.line}`,
      borderRadius: 999, width: 'fit-content',
    }}>
      {options.map(o => {
        const active = o.value === value;
        return (
          <button key={o.value} onClick={() => onChange(o.value)}
            style={{
              padding: '6px 14px', borderRadius: 999, border: 'none',
              background: active ? T.raised : 'transparent',
              color: active ? T.fg : T.fg3,
              fontSize: 12, fontWeight: 600, fontFamily: T.fontUi,
              cursor: 'pointer', letterSpacing: 0.2,
              boxShadow: active ? '0 1px 0 rgba(255,255,255,0.04) inset, 0 1px 3px rgba(0,0,0,0.2)' : 'none',
              transition: 'all 0.15s',
              whiteSpace: 'nowrap',
            }}>
            {o.label}
          </button>
        );
      })}
    </div>
  );
};

// ─────────────────────────────────────────
// カード
// ─────────────────────────────────────────
const Card = ({ children, style = {}, padding = 16, onClick }) => (
  <div onClick={onClick} style={{
    background: T.surface, border: `1px solid ${T.line}`,
    borderRadius: 14, padding, cursor: onClick ? 'pointer' : 'default',
    ...style,
  }}>
    {children}
  </div>
);

// ─────────────────────────────────────────
// メトリックカード(小)
// ─────────────────────────────────────────
const MetricCard = ({ label, value, sub, tone, tooltip, icon }) => {
  return (
    <div style={{
      background: T.surface, border: `1px solid ${T.line}`,
      borderRadius: 12, padding: '12px 14px',
      display: 'flex', flexDirection: 'column', gap: 6,
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      }}>
        <span style={{ fontSize: 11, color: T.fg3, fontWeight: 500, letterSpacing: 0.3, textTransform: 'uppercase', fontFamily: T.fontUi }}>
          {label}
        </span>
        {tooltip && <Icon name="info" size={12} color={T.fg4} />}
      </div>
      <div style={{
        fontFamily: T.fontMono, fontSize: 18, fontWeight: 600,
        color: tone === 'profit' ? T.profit : tone === 'loss' ? T.loss : tone === 'warn' ? T.warn : T.fg,
        fontVariantNumeric: 'tabular-nums', letterSpacing: -0.4, lineHeight: 1.1,
      }}>{value}</div>
      {sub && (
        <div style={{ fontSize: 11, color: T.fg3, fontFamily: T.fontUi }}>{sub}</div>
      )}
    </div>
  );
};

// ─────────────────────────────────────────
// スパークライン
// ─────────────────────────────────────────
const Sparkline = ({ data, width = 100, height = 32, color, fill = true }) => {
  if (!data || data.length === 0) return null;
  const values = data.map(d => typeof d === 'number' ? d : d.running);
  const min = Math.min(...values);
  const max = Math.max(...values);
  const range = max - min || 1;
  const step = width / (values.length - 1 || 1);
  const points = values.map((v, i) => [i * step, height - ((v - min) / range) * height]);
  const path = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(' ');
  const areaPath = `${path} L${width} ${height} L0 ${height} Z`;
  const finalColor = color || (values[values.length - 1] >= values[0] ? T.profit : T.loss);
  const id = 'sg-' + Math.random().toString(36).slice(2, 8);
  return (
    <svg width={width} height={height} style={{ display: 'block' }}>
      {fill && (
        <>
          <defs>
            <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor={finalColor} stopOpacity="0.35" />
              <stop offset="100%" stopColor={finalColor} stopOpacity="0" />
            </linearGradient>
          </defs>
          <path d={areaPath} fill={`url(#${id})`} />
        </>
      )}
      <path d={path} fill="none" stroke={finalColor} strokeWidth="1.5" strokeLinejoin="round" />
    </svg>
  );
};

// ─────────────────────────────────────────
// ボタン
// ─────────────────────────────────────────
const Button = ({ children, variant = 'primary', size = 'md', onClick, disabled, style = {}, icon }) => {
  const variants = {
    primary:   { bg: T.fg, fg: T.bg, bd: T.fg },
    secondary: { bg: T.raised, fg: T.fg, bd: T.line },
    ghost:     { bg: 'transparent', fg: T.fg2, bd: 'transparent' },
    profit:    { bg: T.profit, fg: '#052E15', bd: T.profit },
    loss:      { bg: T.lossBg, fg: T.loss, bd: 'rgba(244,63,94,0.3)' },
    info:      { bg: T.info, fg: '#fff', bd: T.info },
  };
  const sizes = {
    sm: { pad: '6px 12px', fs: 12, h: 30 },
    md: { pad: '10px 16px', fs: 13, h: 40 },
    lg: { pad: '14px 20px', fs: 14, h: 48 },
  };
  const v = variants[variant], s = sizes[size];
  return (
    <button onClick={onClick} disabled={disabled} style={{
      padding: s.pad, minHeight: s.h, borderRadius: 10,
      background: v.bg, color: v.fg, border: `1px solid ${v.bd}`,
      fontSize: s.fs, fontWeight: 600, fontFamily: T.fontUi,
      cursor: disabled ? 'not-allowed' : 'pointer',
      opacity: disabled ? 0.4 : 1,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
      letterSpacing: 0.1,
      transition: 'transform 0.08s, opacity 0.15s',
      ...style,
    }}>
      {icon && <Icon name={icon} size={s.fs + 2} color={v.fg} stroke={2} />}
      {children}
    </button>
  );
};

// ─────────────────────────────────────────
// トップナビ(タイトルバー・ダーク版)
// ─────────────────────────────────────────
const TopBar = ({ title, right, left, sub }) => (
  <div style={{
    padding: '54px 16px 12px', background: T.bg,
    borderBottom: `1px solid ${T.lineSoft}`,
    display: 'flex', flexDirection: 'column', gap: 2,
    position: 'sticky', top: 0, zIndex: 10,
  }}>
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: 30 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        {left}
        <div style={{ fontSize: 20, fontWeight: 700, color: T.fg, fontFamily: T.fontUi, letterSpacing: -0.3 }}>
          {title}
        </div>
      </div>
      <div style={{ display: 'flex', gap: 6 }}>{right}</div>
    </div>
    {sub && <div style={{ fontSize: 12, color: T.fg3, marginTop: 2, fontFamily: T.fontUi }}>{sub}</div>}
  </div>
);

// ─────────────────────────────────────────
// ボトムタブ
// ─────────────────────────────────────────
const BottomTabs = ({ current, onChange }) => {
  const tabs = [
    { id: 'home',  icon: 'home',   label: 'ホーム' },
    { id: 'acc',   icon: 'wallet', label: '口座' },
    { id: 'cal',   icon: 'cal',    label: 'カレンダー' },
    { id: 'ana',   icon: 'chart',  label: '分析' },
    { id: 'more',  icon: 'more',   label: 'その他' },
  ];
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      background: 'rgba(10,11,16,0.85)',
      backdropFilter: 'blur(20px) saturate(180%)',
      WebkitBackdropFilter: 'blur(20px) saturate(180%)',
      borderTop: `1px solid ${T.line}`,
      padding: '6px 8px 22px',
      display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)',
      zIndex: 100,
    }}>
      {tabs.map(t => {
        const active = current === t.id;
        return (
          <button key={t.id} onClick={() => onChange(t.id)} style={{
            background: 'transparent', border: 'none', cursor: 'pointer',
            padding: '6px 0 4px', display: 'flex', flexDirection: 'column',
            alignItems: 'center', gap: 3,
            color: active ? T.fg : T.fg3,
            fontFamily: T.fontUi,
          }}>
            <Icon name={t.icon} size={22} color={active ? T.fg : T.fg3} stroke={active ? 2.2 : 1.7} />
            <span style={{ fontSize: 10, fontWeight: active ? 600 : 500, letterSpacing: 0.1 }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
};

// ─────────────────────────────────────────
// セクション見出し
// ─────────────────────────────────────────
const SectionHead = ({ title, action, actionLabel = '見る' }) => (
  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '0 4px', marginBottom: 10 }}>
    <div style={{ fontSize: 12, color: T.fg3, fontWeight: 600, letterSpacing: 0.6, textTransform: 'uppercase', fontFamily: T.fontUi }}>
      {title}
    </div>
    {action && (
      <button onClick={action} style={{
        background: 'transparent', border: 'none', color: T.fg2, cursor: 'pointer',
        fontSize: 12, fontWeight: 500, fontFamily: T.fontUi,
        display: 'inline-flex', alignItems: 'center', gap: 2,
      }}>{actionLabel} <Icon name="chevR" size={12} color={T.fg2} /></button>
    )}
  </div>
);

// ─────────────────────────────────────────
// 空状態ヒーロー(データ0)
// ─────────────────────────────────────────
const EmptyHero = ({ onStart }) => (
  <div style={{
    margin: '12px 16px', padding: '20px',
    background: `linear-gradient(135deg, ${T.info}22, ${T.info}08)`,
    border: `1px solid ${T.info}40`,
    borderRadius: 14,
    display: 'flex', gap: 14, alignItems: 'center',
  }}>
    <div style={{
      width: 48, height: 48, borderRadius: 12,
      background: T.info, display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
    }}>
      <Icon name="zap" size={24} color="#fff" stroke={2.2} />
    </div>
    <div style={{ flex: 1 }}>
      <div style={{ fontSize: 14, fontWeight: 700, color: T.fg, fontFamily: T.fontUi, marginBottom: 3 }}>
        まだデータがありません
      </div>
      <div style={{ fontSize: 12, color: T.fg2, fontFamily: T.fontUi, lineHeight: 1.5 }}>
        HUBを起動すると口座情報が自動で表示されます
      </div>
    </div>
    <button onClick={onStart} style={{
      background: T.info, color: '#fff', border: 'none',
      padding: '8px 12px', borderRadius: 8, fontSize: 12, fontWeight: 600,
      cursor: 'pointer', fontFamily: T.fontUi, flexShrink: 0,
    }}>
      始める
    </button>
  </div>
);

// Global export
Object.assign(window, {
  Icon, StatusDot, Badge, PnL, PillTabs, Card, MetricCard, Sparkline,
  Button, TopBar, BottomTabs, SectionHead, EmptyHero,
});
