// Saraya Events — shared component atoms.
// React + Babel; exports to window for sibling <script> files.
// Visual language follows the Saraya design system (colors_and_type.css).

const { useState, useEffect, useRef, useContext } = React;

/* ---------- i18n hook ---------- */
// window.LangContext is created in the HTML bridge before this file loads.
function useLang() {
  const ctx = useContext(window.LangContext);
  return ctx;
}

/* ---------- Icon (Lucide via CDN) ---------- */
function Icon({ name, size = 20, stroke = 1.5, style, className }) {
  const ref = useRef(null);
  useEffect(() => {
    if (window.lucide && ref.current) {
      ref.current.innerHTML = '';
      const i = document.createElement('i');
      i.setAttribute('data-lucide', name);
      ref.current.appendChild(i);
      window.lucide.createIcons({ attrs: { width: size, height: size, 'stroke-width': stroke } });
    }
  }, [name, size, stroke]);
  return <span ref={ref} className={className} style={{ display: 'inline-flex', width: size, height: size, color: 'inherit', ...style }} />;
}

/* ---------- Logo ---------- */
function Logo({ height = 44, style }) {
  const logoSrc = (window.__resources && window.__resources.sarayaLogo) || 'assets/logo-primary.png';
  return <img src={logoSrc} alt="Saraya Events" style={{ ...{ height, display: 'block', ...style, width: "46px" }, height: "55px", width: "65px" }} />;
}

/* ---------- Branded image placeholder ----------
   Every image on the site is one of these. Pass `src` to show a real photo;
   otherwise a warm on-brand placeholder renders (gradient + faint icon + label).
   To use real photography later: set src on the data entry, e.g.
     <Img src="assets/photo/raw-022.jpg" ... />                                  */
const TONES = {
  cream: { g: 'linear-gradient(135deg,#FAF6F0 0%,#F1E8D9 55%,#E2D3BC 100%)', fg: 'var(--gold-deep)', dark: false },
  blush: { g: 'linear-gradient(135deg,#FBEFEF 0%,#F0D6D6 55%,#DBAFAF 100%)', fg: 'var(--rose-deep)', dark: false },
  rose: { g: 'linear-gradient(135deg,#F1D3D3 0%,#DDA9A9 55%,#B07878 100%)', fg: '#7A4B4B', dark: false },
  champagne: { g: 'linear-gradient(135deg,#F8F0DA 0%,#E7D29C 55%,#C9A961 100%)', fg: '#7A5E28', dark: false },
  sage: { g: 'linear-gradient(135deg,#ECE6D7 0%,#CFC6A9 55%,#9CAA8C 100%)', fg: '#4F5A43', dark: false },
  espresso: { g: 'linear-gradient(135deg,#4A3930 0%,#33251E 55%,#231914 100%)', fg: 'var(--gold-light)', dark: true }
};

function Img({ src, tone = 'cream', icon = 'flower-2', label, ratio = '4/3', radius = 16, className = '', style, caption, plain, slot, fit = 'cover' }) {
  const tk = TONES[tone] || TONES.cream;
  const admin = React.useContext(window.AdminContext);
  const override = slot && admin && admin.getImg ? admin.getImg(slot) : null;
  const finalSrc = override || src;
  const showOverlay = slot && admin && admin.editMode;
  const common = { aspectRatio: ratio, borderRadius: radius, overflow: 'hidden', position: 'relative', display: 'block' };

  if (finalSrc) {
    return (
      <div className={className} style={{ ...common, background: fit === 'contain' ? 'var(--cream)' : undefined, ...style }}>
        <img src={finalSrc} alt={label || ''} style={{ width: '100%', height: '100%', objectFit: fit, objectPosition: 'center', display: 'block' }} />
        {caption && <CaptionRibbon>{caption}</CaptionRibbon>}
        {showOverlay && <ImgEditOverlay admin={admin} slot={slot} hasImg={true} />}
      </div>);

  }
  return (
    <div className={className} style={{ ...common, background: tk.g, color: tk.fg, ...style }}>
      {/* soft light */}
      <span style={{ position: 'absolute', inset: 0, background: 'radial-gradient(120% 90% at 30% 18%, rgba(255,255,255,0.45), transparent 60%)' }} />
      {!plain &&
      <>
        {/* faint ornament icon */}
        <span style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', opacity: tk.dark ? 0.32 : 0.22 }}>
          <Icon name={icon} size={56} stroke={1} />
        </span>
        {/* hairline frame */}
        <span style={{ position: 'absolute', inset: 10, borderRadius: Math.max(radius - 8, 4), border: `1px solid ${tk.dark ? 'rgba(226,206,154,0.35)' : 'rgba(168,136,74,0.30)'}` }} />
        </>
      }
      {!plain && label &&
      <span style={{
        position: 'absolute', insetInlineStart: 16, bottom: 14, color: tk.fg,
        fontFamily: 'var(--font-body)', fontSize: 11, fontWeight: 600,
        letterSpacing: '0.18em', textTransform: 'uppercase'
      }}>{label}</span>
      }
      {showOverlay && <ImgEditOverlay admin={admin} slot={slot} hasImg={false} />}
    </div>);

}

/* Admin-only overlay: upload / replace / remove an image in a slot */
function ImgEditOverlay({ admin, slot, hasImg }) {
  const stop = (e) => { e.stopPropagation(); e.preventDefault(); };
  return (
    <div className="saraya-img-overlay" onClick={stop}
      style={{ position: 'absolute', inset: 0, zIndex: 15, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 8, background: 'rgba(42,31,26,0.5)', opacity: 0, transition: 'opacity 180ms var(--ease-out)', cursor: 'default' }}>
      <button onClick={(e) => { stop(e); admin.pickImage(slot); }}
        style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '9px 16px', borderRadius: 8, background: 'var(--white)', color: 'var(--fg-primary)', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-body)', fontSize: 13, fontWeight: 600, boxShadow: 'var(--shadow-soft)' }}>
        <Icon name={hasImg ? 'repeat' : 'upload'} size={15} style={{ color: 'var(--gold-deep)' }} />{hasImg ? 'Replace' : 'Upload'}
      </button>
      {hasImg &&
      <button onClick={(e) => { stop(e); admin.removeImg(slot); }}
        style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '7px 14px', borderRadius: 8, background: 'rgba(255,255,255,0.15)', color: '#fff', border: '1px solid rgba(255,255,255,0.5)', cursor: 'pointer', fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 500 }}>
        <Icon name="trash-2" size={13} />Remove
      </button>
      }
    </div>);

}

function CaptionRibbon({ children }) {
  return (
    <span style={{
      position: 'absolute', insetInlineStart: 12, bottom: 10,
      background: 'rgba(42,31,26,0.66)', color: 'var(--ivory)',
      padding: '4px 9px', borderRadius: 4, fontSize: 10,
      letterSpacing: '0.1em', textTransform: 'uppercase', fontFamily: 'var(--font-body)'
    }}>{children}</span>);

}

/* ---------- Button ---------- */
function Button({ variant = 'primary', size = 'md', icon, iconRight, children, onClick, href, type = 'button', disabled, full, style, ...rest }) {
  const sizes = {
    sm: { padding: '9px 16px', fontSize: 13 },
    md: { padding: '13px 24px', fontSize: 14 },
    lg: { padding: '16px 32px', fontSize: 15 }
  };
  const variants = {
    primary: { background: 'var(--espresso)', color: 'var(--ivory)', border: '1px solid var(--espresso)' },
    gold: { background: 'var(--gold)', color: 'var(--espresso)', border: '1px solid var(--gold)' },
    whatsapp: { background: '#1FA855', color: '#fff', border: '1px solid #1FA855' },
    secondary: { background: 'transparent', color: 'var(--fg-primary)', border: '1px solid var(--line-strong)' },
    onDark: { background: 'var(--ivory)', color: 'var(--espresso)', border: '1px solid var(--ivory)' },
    ghost: { background: 'transparent', color: 'var(--fg-primary)', border: '1px solid transparent', padding: '8px 12px' }
  };
  const Comp = href ? 'a' : 'button';
  return (
    <Comp
      href={href} type={href ? undefined : type} onClick={onClick} disabled={disabled}
      className="saraya-btn"
      style={{
        fontFamily: 'var(--font-body)', fontWeight: 500, letterSpacing: '0.04em',
        borderRadius: 8, cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
        transition: 'all 200ms var(--ease-out)', display: full ? 'flex' : 'inline-flex',
        width: full ? '100%' : undefined, justifyContent: 'center',
        alignItems: 'center', gap: 9, textDecoration: 'none', whiteSpace: 'nowrap',
        ...sizes[size], ...variants[variant], ...style
      }}
      {...rest}>
      
      {icon && <Icon name={icon} size={size === 'lg' ? 19 : 17} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === 'lg' ? 19 : 17} />}
    </Comp>);

}

/* ---------- Eyebrow ---------- */
function Eyebrow({ children, color = 'var(--gold-deep)', center, style }) {
  return (
    <div style={{
      fontFamily: 'var(--font-body)', fontSize: 11.5, fontWeight: 600,
      letterSpacing: '0.28em', textTransform: 'uppercase', color,
      display: 'flex', alignItems: 'center', gap: 10,
      justifyContent: center ? 'center' : 'flex-start', ...style
    }}>
      <span style={{ width: 22, height: 1, background: 'currentColor', opacity: 0.55 }} />
      {children}
    </div>);

}

/* ---------- OrnamentRule (gold hairline + diamond) ---------- */
function OrnamentRule({ width = 200, style }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, width, color: 'var(--gold)', ...style }}>
      <span style={{ flex: 1, height: 1, background: 'currentColor', opacity: 0.5 }} />
      <span style={{ width: 6, height: 6, background: 'currentColor', transform: 'rotate(45deg)' }} />
      <span style={{ flex: 1, height: 1, background: 'currentColor', opacity: 0.5 }} />
    </div>);

}

/* ---------- Layout ---------- */
function Container({ children, narrow, wide, style, className }) {
  const max = narrow ? 880 : wide ? 1320 : 1200;
  return (
    <div className={className} style={{ maxWidth: max, margin: '0 auto', paddingInline: 'var(--page-gutter)', ...style }}>
      {children}
    </div>);

}

function Section({ children, bg = 'canvas', style, id, className }) {
  const bgs = {
    canvas: 'var(--bg-canvas)', muted: 'var(--cream)', tint: 'var(--gold-tint)',
    rose: 'var(--rose-tint)', dark: 'var(--espresso)', white: 'var(--white)'
  };
  return (
    <section id={id} className={className} style={{ background: bgs[bg], color: bg === 'dark' ? 'var(--ivory)' : undefined, paddingBlock: 'clamp(56px, 8vw, 104px)', ...style }}>
      {children}
    </section>);

}

/* SectionHead — eyebrow + serif title + optional intro */
function SectionHead({ eyebrow, title, intro, center, onDark, style }) {
  return (
    <div style={{ maxWidth: center ? 720 : 760, margin: center ? '0 auto' : undefined, textAlign: center ? 'center' : 'start', ...style }}>
      {eyebrow && <Eyebrow center={center} color={onDark ? 'var(--gold-light)' : 'var(--gold-deep)'}>{eyebrow}</Eyebrow>}
      {title && <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(30px,4.5vw,52px)', lineHeight: 1.08, fontWeight: 500, margin: '16px 0 0', color: onDark ? 'var(--ivory)' : 'var(--fg-primary)', letterSpacing: '-0.01em' }}>{title}</h2>}
      {intro && <p style={{ marginTop: 18, fontSize: 'clamp(16px,1.6vw,19px)', lineHeight: 1.65, color: onDark ? 'rgba(250,246,240,0.78)' : 'var(--fg-secondary)' }}>{intro}</p>}
    </div>);

}

/* ---------- Reveal (gentle fade-up on scroll) ---------- */
function Reveal({ children, delay = 0, as = 'div', style, className }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;if (!el) return;
    // already in view on mount?
    const r = el.getBoundingClientRect();
    if (r.top < (window.innerHeight || 800)) {setSeen(true);return;}
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => {if (e.isIntersecting) {setSeen(true);io.disconnect();}});
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    // safety: never leave content hidden
    const tm = setTimeout(() => setSeen(true), 1400);
    return () => {io.disconnect();clearTimeout(tm);};
  }, []);
  const Comp = as;
  return (
    <Comp ref={ref} className={className} style={{
      opacity: seen ? 1 : 0, transform: seen ? 'none' : 'translateY(18px)',
      transition: `opacity 600ms var(--ease-out) ${delay}ms, transform 600ms var(--ease-out) ${delay}ms`,
      ...style
    }}>{children}</Comp>);

}

/* ---------- Form atoms ---------- */
function inputStyle(err) {
  return {
    fontFamily: 'var(--font-body)', fontSize: 15, padding: '13px 15px', width: '100%',
    border: '1px solid ' + (err ? 'var(--error)' : 'var(--line-strong)'),
    background: 'var(--white)', borderRadius: 8, color: 'var(--fg-primary)', outline: 'none',
    transition: 'border-color 180ms var(--ease-out), box-shadow 180ms var(--ease-out)'
  };
}
function Field({ label, hint, optional, error, children }) {
  const { t } = useLang();
  return (
    <label style={{ display: 'grid', gap: 7 }}>
      {label && <span style={{ fontSize: 13.5, fontWeight: 500, color: error ? 'var(--error)' : 'inherit' }}>{label}{optional && <span style={{ color: 'var(--fg-muted)', fontWeight: 400 }}> · {t('form.optional')}</span>}</span>}
      {children}
      {hint && <span style={{ fontSize: 12, color: 'var(--fg-muted)' }}>{hint}</span>}
    </label>);

}
function TextInput(props) {
  const [f, setF] = useState(false);
  return <input {...props} onFocus={(e) => {setF(true);props.onFocus && props.onFocus(e);}} onBlur={(e) => {setF(false);props.onBlur && props.onBlur(e);}}
  style={{ ...inputStyle(props.error), ...(f ? { borderColor: 'var(--gold)', boxShadow: '0 0 0 3px var(--gold-tint)' } : {}), ...(props.style || {}) }} />;
}
function Textarea(props) {
  const [f, setF] = useState(false);
  return <textarea rows={props.rows || 4} {...props} onFocus={(e) => {setF(true);props.onFocus && props.onFocus(e);}} onBlur={(e) => {setF(false);props.onBlur && props.onBlur(e);}}
  style={{ ...inputStyle(props.error), resize: 'vertical', minHeight: 96, ...(f ? { borderColor: 'var(--gold)', boxShadow: '0 0 0 3px var(--gold-tint)' } : {}), ...(props.style || {}) }} />;
}
function Select({ children, ...props }) {
  return (
    <div style={{ position: 'relative' }}>
      <select {...props} style={{ ...inputStyle(props.error), appearance: 'none', paddingInlineEnd: 38, cursor: 'pointer', ...(props.style || {}) }}>{children}</select>
      <Icon name="chevron-down" size={16} style={{ position: 'absolute', insetInlineEnd: 14, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: 'var(--fg-secondary)' }} />
    </div>);

}

/* Selectable tile (icon + label) — used in builder/quote */
function OptionTile({ active, icon, children, onClick, style }) {
  return (
    <button type="button" onClick={onClick} style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 9,
      padding: '18px 12px', minHeight: 96, textAlign: 'center', cursor: 'pointer',
      background: active ? 'var(--white)' : 'var(--bg-canvas)',
      border: '1px solid ' + (active ? 'transparent' : 'var(--line)'),
      boxShadow: active ? '0 0 0 2px var(--gold), var(--shadow-soft)' : 'none',
      borderRadius: 14, color: 'var(--fg-primary)', fontFamily: 'var(--font-body)',
      transition: 'all 180ms var(--ease-out)'
    }}>
      {icon && <span style={{ color: active ? 'var(--gold-deep)' : 'var(--slate)' }}><Icon name={icon} size={24} /></span>}
      <span style={{ fontSize: 13.5, fontWeight: 500 }}>{children}</span>
    </button>);

}

/* Pill chip (multi-select) */
function Chip({ active, onClick, icon, children }) {
  return (
    <button type="button" onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', gap: 7, padding: '9px 16px', borderRadius: 999,
      fontFamily: 'var(--font-body)', fontSize: 13.5, fontWeight: 500,
      background: active ? 'var(--espresso)' : 'var(--white)',
      color: active ? 'var(--ivory)' : 'var(--fg-primary)',
      border: '1px solid ' + (active ? 'var(--espresso)' : 'var(--line-strong)'),
      cursor: 'pointer', transition: 'all 180ms var(--ease-out)'
    }}>
      {icon && <Icon name={icon} size={15} />}{children}
    </button>);

}

function Badge({ tone = 'gold', children, style }) {
  const tones = {
    gold: { bg: 'var(--gold-tint)', fg: 'var(--gold-deep)' },
    rose: { bg: 'var(--rose-tint)', fg: 'var(--rose-deep)' },
    dark: { bg: 'var(--espresso)', fg: 'var(--ivory)' },
    cream: { bg: 'var(--cream)', fg: 'var(--fg-primary)' }
  };
  const tk = tones[tone] || tones.gold;
  return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 12px', borderRadius: 999, fontFamily: 'var(--font-body)', fontSize: 11.5, fontWeight: 600, letterSpacing: '0.06em', background: tk.bg, color: tk.fg, ...style }}>{children}</span>;
}

Object.assign(window, {
  useLang, Icon, Logo, Img, CaptionRibbon, Button, Eyebrow, OrnamentRule,
  Container, Section, SectionHead, Reveal, Field, TextInput, Textarea, Select,
  OptionTile, Chip, Badge, TONES
});