// Catatu — Playful primitives v2
// Expanded palette + organic blobs + category icons + sticker decorations

// ── Theme palettes — light (default) and dark (warm, not cold-blue) ──
const CT2_LIGHT = {
  // base
  cream: '#f7f1e3',
  paper: '#fdf8ec',
  ink: '#2a2520',
  ink2: '#5a4f44',
  ink3: '#9c8f7e',
  line: 'rgba(60,45,30,0.08)',
  warmDark: '#1f1916',

  // primary
  terra: '#e07a4f',
  terraDeep: '#c25a32',
  rust: '#a8442a',

  // expanded — playful pastels
  peach: '#fcc7a8',
  salmon: '#f5a48a',
  blush: '#f7d4ce',
  butter: '#f6d35e',
  cream2: '#ffe9b8',
  mint: '#cfe5cd',
  sage: '#9bb585',
  olive: '#7a8b5c',
  lilac: '#d8c5e0',
  lavender: '#bfa6c9',
  sky: '#a8c8d8',
  teal: '#5a8c8a',
  rose: '#e8a0a0',

  // notepaper accents
  postit: '#fff094',
  tape: 'rgba(252,199,168,0.7)',

  // ink-on-pastel — always dark, used for text/icons sitting on pastel bgs
  // (sticky notes, envelope cards, avatar pills) so they stay legible
  // even when the global ink flips to cream in dark mode.
  inkOnPastel: '#2a2520',
  inkOnPastel2: '#5a4f44',
  inkOnPastel3: '#8a7e6e',

  // inverse — for "dark band" surfaces (Amplop summary, accent CTAs) that
  // should stay dark in BOTH themes. These never flip, so the band reads
  // as a deliberately dark inset on light pages and a slightly-darker
  // inset on dark pages.
  inverseBg: '#2a2520',
  inverseInk: '#f7f1e3',
  inverseInk2: 'rgba(247,241,227,0.6)',
};

const CT2_DARK = {
  // base — warm dark, not cold-blue
  cream: '#1a1410',          // main bg
  paper: '#241c17',          // card bg
  ink: '#f5ebd9',            // primary text
  ink2: '#bca893',           // secondary
  ink3: '#7e7060',           // tertiary
  line: 'rgba(245,235,217,0.1)',
  warmDark: '#0c0a08',       // bezel / dark nav bg

  // primary — slightly brighter for dark contrast
  terra: '#e88860',
  terraDeep: '#c25a32',
  rust: '#cd5c3a',

  // category pastels — kept FULL opacity in dark mode too. The envelope cards
  // and category pills use these as backgrounds with hardcoded dark text on top
  // (e.g. rgba(0,0,0,0.5) labels), so we need the pastel to stay light enough
  // for that dark text to remain legible. Pastels-on-warm-dark also reads well
  // aesthetically — like sticky notes glowing on a dark cork board.
  peach: '#fcc7a8',
  salmon: '#f5a48a',
  blush: '#f7d4ce',
  butter: '#f6d35e',
  cream2: '#ffe9b8',
  mint: '#cfe5cd',
  sage: '#9bb585',
  olive: '#a8c08a',          // brighter for accent visibility on dark bg
  lilac: '#d8c5e0',
  lavender: '#bfa6c9',
  sky: '#a8c8d8',
  teal: '#7eb0ad',           // brighter for dark
  rose: '#e8a0a0',

  // notepaper accents
  postit: '#fff094',         // sticky note stays bright (text on it is dark)
  tape: 'rgba(252,199,168,0.55)',

  // ink-on-pastel — always dark, mirrors light palette so envelope cards,
  // sticky notes, and avatar pills remain readable in dark mode too.
  inkOnPastel: '#2a2520',
  inkOnPastel2: '#5a4f44',
  inkOnPastel3: '#8a7e6e',

  // inverse — same fixed values as light mode (always dark band + light text).
  inverseBg: '#2a2520',
  inverseInk: '#f7f1e3',
  inverseInk2: 'rgba(247,241,227,0.6)',
};

// Global theme flag — read from localStorage on init, default light.
// (Wrapped in try/catch in case storage is blocked.)
try {
  const saved = localStorage.getItem('catatu.theme');
  window.__catatuTheme = saved === 'dark' ? 'dark' : 'light';
} catch (e) {
  window.__catatuTheme = 'light';
}

// Proxy: every CT.xxx read returns from the active palette.
// This means `const CT = window.CT2;` captured once at module load
// still gives live theme-aware values on every property access.
window.CT2 = new Proxy({}, {
  get(_target, prop) {
    const palette = window.__catatuTheme === 'dark' ? CT2_DARK : CT2_LIGHT;
    return palette[prop];
  },
  has(_target, prop) {
    return prop in CT2_LIGHT;
  },
  ownKeys() { return Object.keys(CT2_LIGHT); },
  getOwnPropertyDescriptor(_t, prop) {
    return { enumerable: true, configurable: true, value: window.CT2[prop] };
  },
});

// Expose palettes + setter for app code to use
window.CT2_LIGHT = CT2_LIGHT;
window.CT2_DARK = CT2_DARK;
window.setCatatuTheme = function (mode, persist) {
  const next = mode === 'dark' ? 'dark' : 'light';
  window.__catatuTheme = next;
  if (persist !== false) {
    try { localStorage.setItem('catatu.theme', next); } catch (e) {}
  }
  // Update body bg + theme-color meta so browser chrome matches
  const bg = next === 'dark' ? CT2_DARK.cream : CT2_LIGHT.cream;
  if (document.body) {
    document.body.style.background = bg;
    // Also expose theme as a data-attr so CSS can target dark-mode variants of
    // styles that can't easily flip via inline JS (mobile nav glass background,
    // backdrop-filter fallbacks, etc.)
    document.body.setAttribute('data-theme', next);
  }
  if (document.documentElement) {
    document.documentElement.style.background = bg;
    document.documentElement.setAttribute('data-theme', next);
  }
  const meta = document.querySelector('meta[name="theme-color"]');
  if (meta) meta.setAttribute('content', bg);
};
// Apply initial theme to body bg immediately to prevent FOUC
window.setCatatuTheme(window.__catatuTheme);

// ── Organic blob shapes (SVG) ──────────────────────────────────
// NOTE: Named SiteBlob, NOT Blob. A top-level `function Blob() {}` in a
// non-module script clobbers the native window.Blob Web API, which then
// breaks any library that does `new Blob([...])` internally — most
// notably Tesseract.js (used by Scan struk), which builds its worker
// scripts via `URL.createObjectURL(new Blob([code]))` and throws
// "Failed to execute 'createObjectURL' on 'URL': Overload resolution
// failed" when Blob is the React component instead.
function SiteBlob({ kind = 'a', color, size = 200, opacity = 1, style = {} }) {
  const paths = {
    a: 'M50,20 C75,15 95,40 95,60 C95,85 70,95 50,90 C25,95 5,75 10,55 C5,30 30,25 50,20 Z',
    b: 'M50,15 C72,18 90,30 88,55 C92,80 65,92 45,88 C20,90 8,70 12,48 C10,25 30,12 50,15 Z',
    c: 'M50,10 C80,15 92,40 88,65 C82,88 55,95 35,88 C12,80 8,55 15,32 C22,15 38,8 50,10 Z',
    d: 'M50,12 C70,8 90,25 92,50 C95,75 78,90 55,92 C30,95 10,78 12,55 C8,30 28,15 50,12 Z',
    pill: 'M20,50 C20,30 35,15 55,15 C75,15 88,28 88,48 C88,68 72,82 52,82 C32,82 20,70 20,50 Z',
  };
  return (
    <svg viewBox="0 0 100 100" width={size} height={size} style={{ display: 'block', ...style }}>
      <path d={paths[kind] || paths.a} fill={color} opacity={opacity} />
    </svg>
  );
}

// Background blob field — scattered organic shapes
function BlobField({ blobs }) {
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>
      {blobs.map((b, i) => (
        <div key={i} style={{ position: 'absolute', top: b.top, left: b.left, right: b.right, transform: `rotate(${b.rot || 0}deg)` }}>
          <SiteBlob kind={b.kind} color={b.color} size={b.size} opacity={b.opacity ?? 1} />
        </div>
      ))}
    </div>
  );
}

// ── Category icon — colored circle with emoji ──────────────────
function CatIcon({ emoji, color, size = 56, ring = false }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: color, display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.5, position: 'relative',
      boxShadow: ring ? `0 0 0 3px ${window.CT2.cream}, 0 0 0 4px ${color}` : 'none',
    }}>
      <span style={{ filter: 'saturate(0.95)' }}>{emoji}</span>
    </div>
  );
}

const CATEGORIES = [
  { emoji: '🍜', label: 'Makan', color: CT2.peach },
  { emoji: '☕', label: 'Kopi', color: CT2.butter },
  { emoji: '🛵', label: 'Transport', color: CT2.salmon },
  { emoji: '🎬', label: 'Hiburan', color: CT2.lilac },
  { emoji: '🛒', label: 'Belanja', color: CT2.mint },
  { emoji: '💊', label: 'Kesehatan', color: CT2.blush },
  { emoji: '✨', label: 'Lain', color: CT2.cream2 },
];

// ── Sticky note ──────────────────────────────────────────
function StickyNote({ children, color = CT2.postit, rotate = -2, style = {} }) {
  return (
    <div style={{
      background: color, padding: '12px 16px',
      fontFamily: 'Caveat, "Bradley Hand", cursive', fontSize: 16, color: CT2.inkOnPastel,
      transform: `rotate(${rotate}deg)`,
      boxShadow: '0 2px 8px rgba(40,30,20,0.12)',
      maxWidth: 220, lineHeight: 1.3, ...style,
    }}>
      {children}
    </div>
  );
}

// ── Tape strip ──────────────────────────────────────────
function Tape({ width = 80, color = CT2.tape, rotate = 0, style = {} }) {
  return (
    <div style={{
      width, height: 22, background: color,
      transform: `rotate(${rotate}deg)`,
      boxShadow: '0 1px 4px rgba(40,30,20,0.08)',
      ...style,
    }} />
  );
}

// ── Section number badge "①" "②" "③" ────────────────────
function SectionNum({ n, color = CT2.terra }) {
  const circled = ['', '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨'];
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      fontFamily: 'Geist Mono, monospace', fontSize: 12,
      letterSpacing: 1.4, textTransform: 'uppercase',
      color: CT2.ink2,
    }}>
      <span style={{ fontSize: 22, color }}>{circled[n]}</span>
    </div>
  );
}

// ── Underline scribble (hand-drawn feel) ─────────────────
function Scribble({ width = 200, color = CT2.terra, height = 12, style = {} }) {
  return (
    <svg viewBox="0 0 200 12" width={width} height={height} preserveAspectRatio="none" style={{ display: 'block', ...style }}>
      <path d="M2,6 Q40,2 80,7 T160,5 Q180,6 198,4" fill="none" stroke={color} strokeWidth="3" strokeLinecap="round" />
    </svg>
  );
}

// ── Rough rectangle (hand-drawn frame) ───────────────────
function RoughBox({ width, height, color = CT2.ink, strokeWidth = 2, style = {} }) {
  return (
    <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} style={{ display: 'block', ...style }}>
      <path
        d={`M${strokeWidth + 2},${strokeWidth + 4} Q${width / 2},${strokeWidth} ${width - strokeWidth - 1},${strokeWidth + 3}
            Q${width - strokeWidth},${height / 2} ${width - strokeWidth - 2},${height - strokeWidth - 2}
            Q${width / 2},${height} ${strokeWidth + 3},${height - strokeWidth - 1}
            Q${strokeWidth},${height / 2} ${strokeWidth + 2},${strokeWidth + 4} Z`}
        fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round"
      />
    </svg>
  );
}

// ── Full phone bezel container ───────────────────────────
// Screens are designed at a fixed 240x480; this scales them down to `width`.
function PhoneBezel({ width = 240, children, tilt = 0 }) {
  const DESIGN_W = 240;
  const DESIGN_H = 480;
  const scale = width / DESIGN_W;
  const h = DESIGN_H * scale;
  const bezelPad = DESIGN_W * 0.035;
  const radius = DESIGN_W * 0.13;
  const innerRadius = DESIGN_W * 0.1;
  const statusH = DESIGN_W * 0.11;

  return (
    <div style={{
      width, height: h, transform: `rotate(${tilt}deg)`,
      flexShrink: 0, position: 'relative',
    }}>
      <div style={{
        width: DESIGN_W, height: DESIGN_H,
        transform: `scale(${scale})`, transformOrigin: 'top left',
        borderRadius: radius, background: CT2.warmDark,
        padding: bezelPad,
        boxShadow: `0 ${DESIGN_W * 0.1}px ${DESIGN_W * 0.22}px rgba(40,30,20,0.18)`,
        position: 'relative',
      }}>
        <div style={{
          width: '100%', height: '100%', borderRadius: innerRadius, background: CT2.cream,
          overflow: 'hidden', position: 'relative',
        }}>
          {/* status bar */}
          <div style={{
            position: 'absolute', top: 0, left: 0, right: 0, height: statusH,
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            padding: `0 ${DESIGN_W * 0.07}px`, fontFamily: 'DM Sans', fontSize: DESIGN_W * 0.045, fontWeight: 600, color: CT2.ink, zIndex: 10,
          }}>
            <span>9:41</span>
            <div style={{ width: DESIGN_W * 0.32, height: DESIGN_W * 0.08, borderRadius: DESIGN_W * 0.04, background: CT2.warmDark, position: 'absolute', top: DESIGN_W * 0.025, left: '50%', transform: 'translateX(-50%)' }} />
            <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <span style={{ fontSize: DESIGN_W * 0.04 }}>•••</span>
              <span style={{ fontSize: DESIGN_W * 0.04 }}>📶</span>
              <span style={{ fontSize: DESIGN_W * 0.04 }}>🔋</span>
            </div>
          </div>
          <div style={{ paddingTop: statusH, width: '100%', height: '100%', overflow: 'hidden', position: 'relative' }}>
            <div style={{ width: '100%', height: `calc(100% - ${statusH}px)`, position: 'relative' }}>
              {children}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Pin / push-pin decoration ────────────────────────────
function Pin({ color = CT2.terra, size = 16 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: `radial-gradient(circle at 35% 35%, ${color}, ${CT2.rust} 80%)`,
      boxShadow: `0 2px 4px rgba(40,30,20,0.3), inset -1px -1px 2px rgba(0,0,0,0.2)`,
    }} />
  );
}

// Deliberately NOT setting window.Blob — see SiteBlob comment above.
window.SiteBlob = SiteBlob;
window.BlobField = BlobField;
window.CatIcon = CatIcon;
window.CATEGORIES = CATEGORIES;
window.StickyNote = StickyNote;
window.Tape = Tape;
window.SectionNum = SectionNum;
window.Scribble = Scribble;
window.RoughBox = RoughBox;
window.PhoneBezel = PhoneBezel;
window.Pin = Pin;
