// Naviyell — design tokens & atoms
// Inherits from Naviyell_Design_Brief.md §2

const A = {
  // colors
  ink900: '#1A1832',
  ink700: '#2D2B55',
  ink500: '#4A4870',
  ink300: '#B8B5C9',
  ink100: '#E8E5F0',
  gold600: '#B8954A',
  gold500: '#C9A84C',
  gold100: '#F4ECD4',
  paper: '#FAF8F5',
  paper2: '#F2EEE5',
  white: '#FFFFFF',
  success: '#5B8C5A',
  warning: '#C68B4A',
  danger: '#B85450',

  // typography
  serif: '"Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", serif',
  sans: '"Noto Sans JP", "Hiragino Sans", "Yu Gothic", system-ui, sans-serif',
  display: '"Cormorant Garamond", "Noto Serif JP", serif',

  // category colors (for the 5 アンカー categories)
  catMind: '#7A6FB8',     // 心 (purple)
  catBody: '#5B8C5A',     // 体 (green)
  catSurface: '#C68B4A',  // 外見・環境 (warm orange)
  catFuture: '#4A6FA5',   // 未来 (blue)
  catSocial: '#B8754A',   // 社会的 (terracotta)
};

// inject base font + reset once
if (typeof document !== 'undefined' && !document.getElementById('naviyell-tokens')) {
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = 'https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600&family=Noto+Sans+JP:wght@400;500;600;700&family=Noto+Serif+JP:wght@400;500;600;700&display=swap';
  document.head.appendChild(link);

  const s = document.createElement('style');
  s.id = 'naviyell-tokens';
  s.textContent = `
    .ac-screen { font-family: ${A.sans}; color: ${A.ink900}; background: ${A.paper}; }
    .ac-screen *, .ac-screen *::before, .ac-screen *::after { box-sizing: border-box; }
    .ac-screen button { font-family: inherit; }
    .ac-serif { font-family: ${A.serif}; }
    .ac-display { font-family: ${A.display}; }
    .ac-scroll::-webkit-scrollbar { display: none; }
    .ac-scroll { scrollbar-width: none; -ms-overflow-style: none; }
    @keyframes ac-pulse { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
    @keyframes ac-shimmer {
      0% { background-position: -200px 0; }
      100% { background-position: 200px 0; }
    }
  `;
  document.head.appendChild(s);
}

// ─── Atoms ───────────────────────────────────────────────────

function ACButton({ children, variant = 'primary', size = 'md', onClick, disabled, style, fullWidth = true }) {
  const heights = { lg: 56, md: 48, sm: 40 };
  const fontSizes = { lg: 17, md: 16, sm: 14 };
  const variants = {
    primary: { bg: A.gold500, fg: A.ink900, border: 'none', shadow: '0 1px 2px rgba(184,149,74,0.3)' },
    secondary: { bg: 'transparent', fg: A.ink700, border: `1.5px solid ${A.ink700}`, shadow: 'none' },
    tertiary: { bg: 'transparent', fg: A.ink700, border: 'none', shadow: 'none' },
    danger: { bg: 'transparent', fg: A.danger, border: 'none', shadow: 'none' },
  };
  const v = variants[variant];
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      style={{
        height: heights[size],
        width: fullWidth ? '100%' : 'auto',
        padding: fullWidth ? 0 : '0 20px',
        borderRadius: 14,
        background: disabled ? A.ink300 : v.bg,
        color: disabled ? A.white : v.fg,
        border: v.border,
        boxShadow: v.shadow,
        fontSize: fontSizes[size],
        fontWeight: 600,
        letterSpacing: 0.2,
        cursor: disabled ? 'not-allowed' : 'pointer',
        opacity: disabled ? 0.6 : 1,
        transition: 'transform 0.12s, opacity 0.12s',
        ...style,
      }}
      onMouseDown={(e) => !disabled && (e.currentTarget.style.transform = 'scale(0.98)')}
      onMouseUp={(e) => (e.currentTarget.style.transform = 'scale(1)')}
      onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
    >
      {children}
    </button>
  );
}

function ACInput({ label, value, onChange, type = 'text', placeholder, error, style }) {
  return (
    <div style={{ ...style }}>
      {label && (
        <div style={{ fontSize: 13, fontWeight: 500, color: A.ink500, marginBottom: 6 }}>
          {label}
        </div>
      )}
      <input
        type={type}
        value={value || ''}
        onChange={e => onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          width: '100%',
          height: 52,
          padding: '0 16px',
          borderRadius: 12,
          background: A.white,
          border: `1.5px solid ${error ? A.danger : A.ink100}`,
          fontSize: 16,
          color: A.ink900,
          fontFamily: 'inherit',
          outline: 'none',
        }}
        onFocus={(e) => (e.target.style.borderColor = A.gold500)}
        onBlur={(e) => (e.target.style.borderColor = error ? A.danger : A.ink100)}
      />
      {error && <div style={{ fontSize: 12, color: A.danger, marginTop: 4 }}>{error}</div>}
    </div>
  );
}

function ACPill({ children, active, onClick, color }) {
  return (
    <button
      onClick={onClick}
      style={{
        height: 36,
        padding: '0 16px',
        borderRadius: 18,
        background: active ? (color || A.gold100) : A.white,
        color: active ? (color ? A.white : A.gold600) : A.ink500,
        border: active ? `1px solid ${color || A.gold500}` : `1px solid ${A.ink100}`,
        fontSize: 13,
        fontWeight: 600,
        cursor: 'pointer',
        whiteSpace: 'nowrap',
        flexShrink: 0,
        fontFamily: 'inherit',
      }}
    >
      {children}
    </button>
  );
}

function ACAvatar({ size = 40, name = '?', src, color }) {
  const initial = name.charAt(0);
  const palette = [A.catMind, A.catBody, A.catSurface, A.catFuture, A.catSocial, A.ink700];
  const bg = color || palette[name.charCodeAt(0) % palette.length];
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: src ? `center/cover url(${src})` : bg,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: A.white, fontWeight: 600, fontSize: size * 0.4,
      flexShrink: 0,
      fontFamily: A.serif,
    }}>
      {!src && initial}
    </div>
  );
}

function ACBadge({ children, tone = 'neutral', style }) {
  const tones = {
    success: { bg: '#E8F0E5', fg: A.success },
    warning: { bg: '#FBEFD9', fg: A.warning },
    info: { bg: '#E3E5F0', fg: A.ink700 },
    gold: { bg: A.gold100, fg: A.gold600 },
    neutral: { bg: A.paper2, fg: A.ink500 },
    danger: { bg: '#F5DDD9', fg: A.danger },
  };
  const t = tones[tone];
  return (
    <span style={{
      padding: '3px 10px',
      borderRadius: 8,
      background: t.bg,
      color: t.fg,
      fontSize: 11,
      fontWeight: 600,
      letterSpacing: 0.3,
      ...style,
    }}>{children}</span>
  );
}

function ACStars({ rating = 0, size = 12 }) {
  return (
    <span style={{ display: 'inline-flex', gap: 1, alignItems: 'center' }}>
      {[1,2,3,4,5].map(i => (
        <svg key={i} width={size} height={size} viewBox="0 0 16 16">
          <path
            d="M8 1l2.2 4.5 5 .7-3.6 3.5.85 4.95L8 12.3l-4.45 2.35.85-4.95L.8 6.2l5-.7L8 1z"
            fill={i <= Math.round(rating) ? A.gold500 : A.ink100}
          />
        </svg>
      ))}
    </span>
  );
}

function ACMoon({ size = 16, color }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" fill={color || A.gold500}/>
    </svg>
  );
}

function ACStar({ size = 8, x, y, opacity = 0.6 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 8 8" style={{ position: 'absolute', left: x, top: y, opacity }}>
      <path d="M4 0L4.6 3.4L8 4L4.6 4.6L4 8L3.4 4.6L0 4L3.4 3.4L4 0z" fill={A.gold500}/>
    </svg>
  );
}

// ─── Top app bar ─────────────────────────────────────────────
function ACTopBar({ title, leading, trailing, dark, transparent }) {
  return (
    <div style={{
      paddingTop: 47, // iOS status bar / Dynamic Island clearance
      padding: '47px 8px 0',
      background: transparent ? 'transparent' : (dark ? A.ink900 : A.paper),
      flexShrink: 0,
    }}>
      <div style={{
        height: 52,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        borderBottom: transparent ? 'none' : `1px solid ${A.ink100}`,
      }}>
        <div style={{ width: 44, display: 'flex', justifyContent: 'center' }}>
          {leading || <div />}
        </div>
        <div style={{
          flex: 1, textAlign: 'center', fontSize: 16, fontWeight: 600,
          color: dark ? A.white : A.ink900,
          fontFamily: A.serif,
        }}>{title}</div>
        <div style={{ width: 44, display: 'flex', justifyContent: 'center' }}>
          {trailing || <div />}
        </div>
      </div>
    </div>
  );
}

function ACBack({ onClick, dark, fallback = 'home' }) {
  const nav = (typeof window !== 'undefined' && window.useNav) ? window.useNav() : null;
  const handler = onClick || (nav ? () => nav.back(fallback) : undefined);
  return (
    <button onClick={handler} style={{
      width: 44, height: 44, border: 'none', background: 'transparent',
      cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <svg width="11" height="18" viewBox="0 0 11 18" fill="none">
        <path d="M9 1L1 9l8 8" stroke={dark ? A.white : A.ink900} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    </button>
  );
}

// ─── Bottom tab bar ──────────────────────────────────────────
function ACTabBar({ active = 'home', onTab }) {
  const nav = (typeof window !== 'undefined' && window.useNav) ? window.useNav() : null;
  const tabHandler = onTab || (nav ? nav.tab : undefined);
  const tabs = [
    { id: 'home',     label: 'ホーム',     icon: 'home' },
    { id: 'browse',   label: '探す',       icon: 'search' },
    { id: 'messages', label: 'メッセージ', icon: 'chat' },
    { id: 'tracker',  label: 'トラッカー', icon: 'check' },
    { id: 'mypage',   label: 'マイページ', icon: 'user' },
  ];
  return (
    <div style={{
      height: 84,
      paddingTop: 8,
      paddingBottom: 30,
      background: A.white,
      borderTop: `1px solid ${A.ink100}`,
      display: 'flex',
      flexShrink: 0,
    }}>
      {tabs.map(t => {
        const on = active === t.id;
        const color = on ? A.gold600 : A.ink500;
        return (
          <button key={t.id} onClick={() => tabHandler && tabHandler(t.id)} style={{
            flex: 1, border: 'none', background: 'transparent',
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
            cursor: 'pointer', padding: 0,
          }}>
            <ACTabIcon name={t.icon} color={color} filled={on} />
            <span style={{ fontSize: 10, fontWeight: on ? 600 : 500, color, fontFamily: 'inherit' }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function ACTabIcon({ name, color, filled }) {
  const sw = 1.7;
  switch (name) {
    case 'home':
      return <svg width="24" height="24" viewBox="0 0 24 24" fill={filled ? color : 'none'} stroke={color} strokeWidth={sw}>
        <path d="M3 10.5L12 3l9 7.5V20a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1v-9.5z" strokeLinejoin="round"/>
      </svg>;
    case 'search':
      return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={sw}>
        <circle cx="11" cy="11" r="7" fill={filled ? color : 'none'} fillOpacity={filled ? 0.15 : 0}/>
        <path d="M16.5 16.5L21 21" strokeLinecap="round"/>
      </svg>;
    case 'chat':
      return <svg width="24" height="24" viewBox="0 0 24 24" fill={filled ? color : 'none'} stroke={color} strokeWidth={sw}>
        <path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-7l-4 3.5V17H6a2 2 0 0 1-2-2V6z" strokeLinejoin="round"/>
      </svg>;
    case 'check':
      return <svg width="24" height="24" viewBox="0 0 24 24" fill={filled ? color : 'none'} stroke={color} strokeWidth={sw}>
        <circle cx="12" cy="12" r="9"/>
        <path d="M8 12.5l3 3 5-6" strokeLinecap="round" strokeLinejoin="round" stroke={filled ? A.white : color}/>
      </svg>;
    case 'user':
      return <svg width="24" height="24" viewBox="0 0 24 24" fill={filled ? color : 'none'} stroke={color} strokeWidth={sw}>
        <circle cx="12" cy="8" r="4"/>
        <path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8" strokeLinecap="round"/>
      </svg>;
    default: return null;
  }
}

// ─── Sticky bottom CTA bar ───────────────────────────────────
function ACStickyCTA({ children }) {
  return (
    <div style={{
      padding: '12px 20px 32px',
      background: A.white,
      borderTop: `1px solid ${A.ink100}`,
      flexShrink: 0,
    }}>
      {children}
    </div>
  );
}

// ─── Section header ──────────────────────────────────────────
function ACSectionHeader({ title, action, onAction }) {
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', padding: '0 20px', marginBottom: 12 }}>
      <h2 style={{ margin: 0, fontFamily: A.serif, fontSize: 18, fontWeight: 600, color: A.ink900 }}>
        {title}
      </h2>
      {action && (
        <button onClick={onAction} style={{
          border: 'none', background: 'transparent', color: A.gold600,
          fontSize: 13, fontWeight: 500, cursor: 'pointer', padding: 0, fontFamily: 'inherit',
        }}>{action}</button>
      )}
    </div>
  );
}

// ─── Card ────────────────────────────────────────────────────
function ACCard({ children, style, onClick, padding = 16 }) {
  return (
    <div
      onClick={onClick}
      style={{
        background: A.white,
        borderRadius: 16,
        padding,
        boxShadow: '0 1px 2px rgba(26,24,50,0.04), 0 4px 12px rgba(26,24,50,0.04)',
        border: `1px solid ${A.ink100}`,
        cursor: onClick ? 'pointer' : 'default',
        ...style,
      }}
    >
      {children}
    </div>
  );
}

// ─── Loading state — moon phase morph ─────────────────────────
function ACMoonLoader({ size = 48, label = '読み込み中...', dark = true }) {
  const id = React.useMemo(() => 'mp-' + Math.random().toString(36).slice(2, 8), []);
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
      padding: 24, color: dark ? A.paper : A.ink700,
    }}>
      <svg width={size} height={size} viewBox="0 0 48 48">
        <defs>
          <radialGradient id={id} cx="40%" cy="40%">
            <stop offset="0%" stopColor="#F4ECD4"/>
            <stop offset="100%" stopColor="#9590A0"/>
          </radialGradient>
          <clipPath id={id + '-clip'}>
            <circle cx="24" cy="24" r={size === 48 ? 14 : size * 0.3}/>
          </clipPath>
        </defs>
        <circle cx="24" cy="24" r={size === 48 ? 14 : size * 0.3} fill={`url(#${id})`}/>
        <g clipPath={`url(#${id}-clip)`}>
          <circle cx="38" cy="24" r={size === 48 ? 14 : size * 0.3} fill={dark ? A.ink900 : A.paper}>
            <animate attributeName="cx" values="38;24;10;24;38" dur="3s" repeatCount="indefinite"/>
          </circle>
        </g>
      </svg>
      {label && (
        <div style={{ fontSize: 12, letterSpacing: 1, opacity: 0.75 }}>{label}</div>
      )}
    </div>
  );
}

Object.assign(window, {
  A, ACButton, ACInput, ACPill, ACAvatar, ACBadge, ACStars,
  ACMoon, ACStar, ACTopBar, ACBack, ACTabBar, ACStickyCTA,
  ACSectionHeader, ACCard, ACMoonLoader,
});
