/* AutoVault — content + icon library. Exposed on window. */

const WA_NUMBER = "628170812074";
const WA_TEXT = encodeURIComponent("Halo AutoVault, I'd like to book a private tour of the vault.");
const WA_LINK = `https://wa.me/${WA_NUMBER}?text=${WA_TEXT}`;

const NAV_LINKS = [
  { label: "The Vault", href: "/" },
  { label: "Services", href: "/services" },
  { label: "Facility", href: "/facility" },
  { label: "Membership", href: "/membership" },
  { label: "Journal", href: "/journal" },
];

const TRUST = ["24/7 CCTV", "Climate-Controlled", "Fully Insured", "App Access"];

const THREATS = [
  { n: "01", t: "Tropical humidity", d: "Jakarta's heat and damp breed mould in leather, haze on paint, and corrosion you won't see until it's permanent." },
  { n: "02", t: "Flat batteries", d: "A car left a fortnight wakes up dead. Stored long enough, the whole electrical system suffers." },
  { n: "03", t: "Apartment parking", d: "Tower basements mean valet dents, careless neighbours, and zero climate control for a seven-figure machine." },
  { n: "04", t: "Theft & exposure", d: "Exotics are targets. Open lots and shared garages offer a thief everything but the keys." },
];

const SERVICES = [
  { n: "01", t: "Secure Storage", d: "Individually bayed, access-logged, and watched around the clock. Your car, untouched until you want it.", ico: "vault" },
  { n: "02", t: "Climate-Controlled Vault", d: "A/C and dehumidification hold a constant, gentle climate — the conditions paint, rubber and leather were made to live in.", ico: "climate" },
  { n: "03", t: "CTEK Battery Tending", d: "Every stored car stays on a CTEK conditioner. Turn the key after months away and it fires on the first crank.", ico: "battery" },
  { n: "04", t: "Detailing & Ceramic Coating", d: "In-house detailers and certified ceramic coating. Your car leaves the vault better than it arrived.", ico: "detail" },
  { n: "05", t: "24/7 Surveillance", d: "Multi-camera CCTV, motion alerts and on-site security. Nothing moves in the vault unseen.", ico: "cctv" },
  { n: "06", t: "App Valet Pickup", d: "Request your car from the app. We have it warmed, cleaned and ready — collected or delivered on schedule.", ico: "app" },
  { n: "07", t: "Enclosed Transport", d: "Covered flatbed collection and delivery across Jakarta. Your car never touches a public road on its own wheels.", ico: "transport" },
];

const FACILITY_FEATURES = [
  { fi: "A", h: "Vault-grade access control", p: "Biometric entry, individual bay logs, and a chain-of-custody record for every movement." },
  { fi: "B", h: "Active climate management", p: "Continuous A/C and dehumidification monitored 24/7, tuned to preservation conditions." },
  { fi: "C", h: "Fire suppression & monitoring", p: "Clean-agent suppression and smoke detection engineered around fuel, not furniture." },
];

const SPECS = [
  { v: 64, u: "", l: "CCTV cameras" },
  { v: 100, u: "%", l: "Climate coverage" },
  { v: 24, u: "/7", l: "On-site security" },
  { v: 0, u: "", l: "Cars ever lost", suffix: true },
];

const STEPS = [
  { k: "Step 01", t: "Book your bay", d: "Reserve in minutes — by app or WhatsApp concierge. Choose your tier, tell us about your car.", ph: "Booking flow · app screen" },
  { k: "Step 02", t: "We collect", d: "An enclosed flatbed arrives at your door. Your car is loaded, logged and delivered to its bay.", ph: "Enclosed flatbed · night collection" },
  { k: "Step 03", t: "Track & request", d: "Watch its status, schedule a detail, or request pickup — all from the app, whenever you like.", ph: "App · vault dashboard" },
];

const TIERS = [
  {
    name: "Garage", for: "The weekend car",
    feats: [
      { t: "Secure individual bay", on: true },
      { t: "24/7 CCTV & security", on: true },
      { t: "CTEK battery tending", on: true },
      { t: "App status & access", on: true },
      { t: "Climate-controlled vault", on: false },
      { t: "Quarterly detailing", on: false },
    ],
  },
  {
    name: "Vault", for: "The collector", pop: true,
    feats: [
      { t: "Everything in Garage", on: true },
      { t: "Climate-controlled vault", on: true },
      { t: "Monthly wash & inspection", on: true },
      { t: "Enclosed transport (2 / yr)", on: true },
      { t: "Priority app valet pickup", on: true },
      { t: "Quarterly ceramic top-up", on: false },
    ],
  },
  {
    name: "Concierge", for: "The connoisseur",
    feats: [
      { t: "Everything in Vault", on: true },
      { t: "Unlimited enclosed transport", on: true },
      { t: "Full detailing & coating", on: true },
      { t: "Dedicated account manager", on: true },
      { t: "Event & track delivery", on: true },
      { t: "Private lounge access", on: true },
    ],
  },
];

const TESTIMONIALS = [
  { q: "I used to check my phone at 2am wondering about the car. Now I don't. They treat it better than I did — and I'm fussy.", by: "Reza A.", role: "Ferrari 296 owner · Jakarta" },
  { q: "Handed over the keys, watched the vault door close, and felt something I hadn't felt about storage before: relief.", by: "Daniel & Mira", role: "Classic collection · 4 cars" },
  { q: "Flew out for three months. Came back, opened the app, car was warmed and detailed at my door by 9am. Effortless.", by: "Stefan K.", role: "Expat · Porsche 911 GT3" },
];

const STORED_BRANDS = ["Ferrari", "Lamborghini", "Porsche", "McLaren", "Aston Martin", "Mercedes-AMG", "Bentley", "Rolls-Royce"];

const POSTS = [
  { cat: "Preservation", t: "How to store a classic car in Indonesia's tropical climate", meta: "8 min read · Jun 2026", ph: "Classic interior · detail" },
  { cat: "Battery Care", t: "Why your battery dies when the car sits — and the CTEK fix", meta: "6 min read · May 2026", ph: "CTEK conditioner · macro" },
  { cat: "Detailing", t: "Ceramic coating: genuinely worth it, or just hype?", meta: "9 min read · May 2026", ph: "Paint reflection · ceramic" },
];

/* ---------------- icon set (stroke, inherits currentColor) ---------------- */
function Ico({ name, className }) {
  const s = { fill: "none", stroke: "currentColor", strokeWidth: 1.4, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    vault: <g {...s}><rect x="3" y="4" width="18" height="16" rx="1.5"/><circle cx="12" cy="12" r="4.2"/><path d="M12 7.8v1.4M12 14.8v1.4M7.8 12h1.4M14.8 12h1.4"/><circle cx="12" cy="12" r="1"/></g>,
    climate: <g {...s}><path d="M12 3v18M12 7l3-3M12 7L9 4M12 17l3 3M12 17l-3 3"/><path d="M4 12h16M8 9l-3 3 3 3M16 9l3 3-3 3"/></g>,
    battery: <g {...s}><rect x="3" y="8" width="15" height="9" rx="1.5"/><path d="M18 11h2.5v3H18M7 10v5M7 12.5h-2M11 10v5"/><path d="M14 9l1.5-3"/></g>,
    detail: <g {...s}><path d="M5 16c0-4 3.2-7 7-7s7 3 7 7"/><path d="M3 16h18"/><path d="M9 9.5l1-2.5h4l1 2.5"/><circle cx="7.5" cy="16" r="0.6" fill="currentColor"/><circle cx="16.5" cy="16" r="0.6" fill="currentColor"/></g>,
    cctv: <g {...s}><path d="M4 7l13-3 1.2 4L5.2 11z"/><path d="M5.2 11l1 4M9 14v3.5a2 2 0 0 1-2 2H5"/><path d="M17.2 8l3-0.8"/></g>,
    app: <g {...s}><rect x="7" y="3" width="10" height="18" rx="2"/><path d="M11 18h2"/><path d="M9.5 7.5l2 2 3.5-3.5"/></g>,
    transport: <g {...s}><path d="M2 16h2M20 16h2M4 16V9l5-2h6l3 4v5"/><circle cx="7.5" cy="16.5" r="1.8"/><circle cx="16.5" cy="16.5" r="1.8"/><path d="M9.5 16h5M9 9v2h7"/></g>,
  };
  return <svg viewBox="0 0 24 24" className={className} aria-hidden="true">{paths[name]}</svg>;
}

function WhatsAppIcon({ className, style }) {
  return (
    <svg viewBox="0 0 24 24" className={className} style={style} fill="currentColor" aria-hidden="true">
      <path d="M12.04 2C6.58 2 2.13 6.45 2.13 11.91c0 1.75.46 3.45 1.32 4.95L2 22l5.25-1.38a9.9 9.9 0 0 0 4.79 1.22h.01c5.46 0 9.91-4.45 9.91-9.91 0-2.65-1.03-5.14-2.9-7.01A9.82 9.82 0 0 0 12.04 2Zm0 1.8c2.16 0 4.19.84 5.72 2.37a8.05 8.05 0 0 1 2.37 5.74c0 4.46-3.63 8.09-8.1 8.09a8.1 8.1 0 0 1-4.13-1.13l-.3-.18-3.12.82.83-3.04-.19-.31a8.07 8.07 0 0 1-1.24-4.3c0-4.46 3.63-8.1 8.1-8.1Zm-4.6 4.38c-.21 0-.55.08-.84.39-.29.31-1.1 1.07-1.1 2.62s1.13 3.04 1.29 3.25c.16.21 2.22 3.39 5.38 4.75.75.32 1.34.51 1.79.66.75.24 1.44.2 1.98.12.6-.09 1.86-.76 2.12-1.49.26-.73.26-1.36.18-1.49-.08-.13-.29-.21-.6-.37-.31-.16-1.86-.92-2.15-1.02-.29-.11-.5-.16-.71.16-.21.31-.81 1.02-1 1.23-.18.21-.37.24-.68.08-.31-.16-1.32-.49-2.51-1.55-.93-.83-1.56-1.85-1.74-2.17-.18-.31-.02-.48.14-.64.14-.14.31-.37.47-.55.16-.18.21-.31.31-.52.1-.21.05-.39-.03-.55-.08-.16-.71-1.72-.97-2.35-.26-.62-.51-.54-.71-.55h-.6Z"/>
    </svg>
  );
}

function Shield({ className }) {
  // brand crest: shield silhouette with a low car form cut into it
  return (
    <svg viewBox="0 0 52 64" className={className} aria-hidden="true">
      <path d="M26 1.5 49 9.2v22.5c0 16.2-10.4 25.7-23 30.8C13.4 57.4 3 47.9 3 31.7V9.2L26 1.5Z"/>
      <path className="car" d="M14.5 36.5c.6-.3 1.1-1.6 1.7-2.4 1-1.4 2.4-2.2 4.4-2.5 1.7-.25 3.3-.9 4.4-1.5 2.6-1.4 5-1.9 8-1.6 1.6.16 3 .6 4 1.6.6.6 1.7.9 2.6 1 .9.1 1.4.7 1.4 1.6 0 1-.1 2-.4 2.5-.2.4-.7.6-1.3.6H15.7c-.8 0-1.5-.5-1.2-1.3Z"/>
      <circle className="car" cx="20" cy="37.2" r="2"/>
      <circle className="car" cx="33.5" cy="37.2" r="2"/>
    </svg>
  );
}

function Arrow({ className, style }) {
  return <svg viewBox="0 0 24 24" className={className} style={style} fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
}

/* ---------------- placeholder ---------------- */
function Placeholder({ label, kind = "image", className = "", style }) {
  return (
    <div className={`ph ${className}`} style={style}>
      <span className="ph__tag"><b>{kind}</b> · {label}</span>
    </div>
  );
}

/* ---------------- user-fillable image slot (drag-drop real car photos) ---- */
function Shot({ id, label, fill = false, ratio, style }) {
  const base = fill
    ? { position: "absolute", inset: 0, width: "100%", height: "100%", display: "block" }
    : { display: "block", width: "100%", height: "auto", aspectRatio: ratio || "3 / 2" };
  return React.createElement("image-slot", {
    id, placeholder: label, shape: "rect",
    src: `assets/images/${id}.jpg`,
    style: { ...base, ...style },
  });
}

/* ---------------- reveal on scroll ---------------- */
function useReveal() {
  React.useEffect(() => {
    const els = document.querySelectorAll(".reveal:not(.in)");
    if (!els.length) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      els.forEach((e) => e.classList.add("in"));
      return;
    }
    const io = new IntersectionObserver((ents) => {
      ents.forEach((en) => { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } });
    }, { threshold: 0.14, rootMargin: "0px 0px -8% 0px" });
    els.forEach((e) => io.observe(e));
    return () => io.disconnect();
  });
}

function Reveal({ children, delay = 0, as = "div", className = "", ...rest }) {
  const Tag = as;
  return <Tag className={`reveal ${className}`} style={{ "--rd": `${delay}ms` }} {...rest}>{children}</Tag>;
}

/* ---------------- count up ---------------- */
function CountUp({ to, suffix = "" }) {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) { setVal(to); return; }
    let started = false;
    const io = new IntersectionObserver((ents) => {
      ents.forEach((en) => {
        if (en.isIntersecting && !started) {
          started = true;
          const dur = 1500; const t0 = performance.now();
          const tick = (t) => {
            const p = Math.min(1, (t - t0) / dur);
            const e = 1 - Math.pow(1 - p, 3);
            setVal(Math.round(e * to));
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
          io.unobserve(el);
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [to]);
  return <span ref={ref}>{val}{suffix}</span>;
}

Object.assign(window, {
  WA_NUMBER, WA_LINK, NAV_LINKS, TRUST, THREATS, SERVICES, FACILITY_FEATURES,
  SPECS, STEPS, TIERS, TESTIMONIALS, STORED_BRANDS, POSTS,
  Ico, WhatsAppIcon, Shield, Arrow, Placeholder, Shot, useReveal, Reveal, CountUp,
});
