// Shared UI: icons, Nav, Footer, MailingList, Modal, Toast
const { useState, useEffect, useRef } = React;

// ---- Icons (inline SVG, stroke-based) ----------------------------
const Icon = {
  Needle: ({ size = 20 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 21L20 4" />
      <circle cx="20" cy="4" r="1.2" />
      <path d="M5 19l4-1 1-4" strokeDasharray="2 2" />
    </svg>,

  Scissors: ({ size = 20 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="6" cy="6" r="3" />
      <circle cx="6" cy="18" r="3" />
      <path d="M20 4L9 15" />
      <path d="M14 13l6 7" />
      <path d="M9 9l3 3" />
    </svg>,

  Heart: ({ size = 20 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 21s-7-4.5-9.5-9A5 5 0 0112 6a5 5 0 019.5 6c-2.5 4.5-9.5 9-9.5 9z" />
    </svg>,

  Bag: ({ size = 20 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 8h14l-1 12H6L5 8z" />
      <path d="M9 8a3 3 0 016 0" />
    </svg>,

  Mail: ({ size = 18 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="5" width="18" height="14" rx="2" />
      <path d="M3 7l9 6 9-6" />
    </svg>,

  Phone: ({ size = 18 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 4h3l2 5-2 1a12 12 0 006 6l1-2 5 2v3a2 2 0 01-2 2A16 16 0 013 6a2 2 0 012-2z" />
    </svg>,

  Pin: ({ size = 18 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 22s7-7 7-12a7 7 0 10-14 0c0 5 7 12 7 12z" />
      <circle cx="12" cy="10" r="2.5" />
    </svg>,

  Clock: ({ size = 18 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="9" />
      <path d="M12 7v5l3 2" />
    </svg>,

  Close: ({ size = 18 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
      <path d="M5 5l14 14M19 5L5 19" />
    </svg>,

  Plus: ({ size = 16 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <path d="M12 5v14M5 12h14" />
    </svg>,

  Trash: ({ size = 16 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" />
    </svg>,

  Edit: ({ size = 16 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 20h4l11-11-4-4L4 16v4z" />
    </svg>,

  Arrow: ({ size = 16 }) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 12h14M13 5l7 7-7 7" />
    </svg>

};

// ---- Logo ---------------------------------------------------------
function Brand({ onClick }) {
  return (
    <a className="brand" href="#" onClick={(e) => {e.preventDefault();onClick && onClick();}}>
      <span className="brand-mark" aria-hidden="true">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
          <path d="M3 18L21 6" strokeDasharray="3 3" />
          <circle cx="3" cy="18" r="1.2" fill="currentColor" />
        </svg>
      </span>
      <span style={{ fontSize: "15px", fontWeight: 700 }}>Holibags</span>
    </a>);

}

// ---- Nav ----------------------------------------------------------
const NAV_ITEMS = [
{ id: "home", label: "Home" },
{ id: "products", label: "Products" },
{ id: "contact", label: "Contact" }];


function Nav({ page, navigate, cartCount }) {
  const [open, setOpen] = useState(false);
  useEffect(() => {setOpen(false);}, [page]);
  return (
    <header className="nav" role="banner">
      <div className="nav-inner" style={{ fontWeight: "100" }}>
        <Brand onClick={() => navigate("home")} />
        <nav className="nav-links" aria-label="Primary">
          {NAV_ITEMS.map((item) =>
          <a
            key={item.id}
            href="#"
            className={"nav-link" + (page === item.id ? " active" : "")}
            onClick={(e) => {e.preventDefault();navigate(item.id);}}>
            
              {item.label}
            </a>
          )}
        </nav>
        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
          <button
            className="btn btn-ghost btn-sm"
            onClick={() => navigate("cart")}
            aria-label={`Cart (${cartCount} items)`}
            style={{ position: "relative" }}>

            <Icon.Bag size={18} />
            <span style={{ marginLeft: 4 }}>Cart</span>
            {cartCount > 0 &&
            <span style={{
              position: "absolute", top: 0, right: -2,
              background: "var(--accent)", color: "var(--accent-on)",
              borderRadius: 999, fontSize: 11, fontWeight: 700,
              width: 18, height: 18, display: "grid", placeItems: "center"
            }}>{cartCount}</span>
            }
          </button>
          <a className="btn btn-primary btn-sm nav-cta" href="#"
          onClick={(e) => {e.preventDefault();navigate("cart");}}>
            Go to checkout
          </a>
          <button className="hamburger" aria-label="Open menu" aria-expanded={open}
          onClick={() => setOpen(true)}>
            <span /><span /><span />
          </button>
        </div>
      </div>

      <div className={"mobile-menu" + (open ? " open" : "")} aria-hidden={!open}>
        <div className="mobile-menu-head">
          <Brand onClick={() => {setOpen(false);navigate("home");}} />
          <button className="hamburger" aria-label="Close menu" onClick={() => setOpen(false)}>
            <Icon.Close />
          </button>
        </div>
        <div className="mobile-menu-links">
          {NAV_ITEMS.map((item) =>
          <a
            key={item.id}
            href="#"
            className={"mobile-menu-link" + (page === item.id ? " active" : "")}
            onClick={(e) => {e.preventDefault();setOpen(false);navigate(item.id);}}>
            
              {item.label}
            </a>
          )}
          <a href="#" className="mobile-menu-link"
          onClick={(e) => {e.preventDefault();setOpen(false);navigate("cart");}}>
            Cart {cartCount > 0 && <span style={{ color: "var(--accent)" }}>({cartCount})</span>}
          </a>
        </div>
        <div style={{ marginTop: "auto", display: "flex", gap: 8 }}>
          <a className="btn btn-primary" style={{ flex: 1 }} href="#"
          onClick={(e) => {e.preventDefault();setOpen(false);navigate("cart");}}>
            Go to checkout
          </a>
        </div>
      </div>
    </header>);

}

// ---- Mailing list -------------------------------------------------
function MailingList({ variant = "light" }) {
  const [email, setEmail] = useState("");
  const [err, setErr] = useState("");
  const [done, setDone] = useState(false);

  function submit(e) {
    e.preventDefault();
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      setErr("Please enter a valid email address.");
      return;
    }
    setErr("");
    fetch("/mailing_list", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, source: variant === "dark" ? "footer" : "page" }),
    }).then((r) => r.ok ? r.json() : Promise.reject(r))
      .catch((e) => console.error("[mailing list]", e));
    setDone(true);
    setEmail("");
    setTimeout(() => setDone(false), 4000);
  }

  return (
    <form className="mailing-form" onSubmit={submit} noValidate>
      <div className="mailing">
        <input
          className="input"
          type="email"
          required
          placeholder="you@example.com"
          aria-label="Email address"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          style={{ flex: 1, minWidth: 200 }} />
        
        <button className="btn btn-primary" type="submit">Subscribe</button>
      </div>
      {err && <div className="error-text" style={{ marginTop: 8 }}>{err}</div>}
      {done && <div style={{ marginTop: 8, fontSize: 14, color: variant === "dark" ? "var(--rose)" : "var(--accent)" }}>
        Thanks — you're on the list.</div>}
    </form>);

}

// ---- Footer -------------------------------------------------------
function Footer({ navigate, hours }) {
  const list = Array.isArray(hours) && hours.length ? hours : DEFAULT_HOURS;
  return (
    <footer className="footer" role="contentinfo">
      <div className="container">
        <div className="footer-grid">
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
              <span className="brand-mark" style={{ borderColor: "var(--rose)", color: "var(--rose)" }}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
                  <path d="M3 18L21 6" strokeDasharray="3 3" />
                  <circle cx="3" cy="18" r="1.2" fill="currentColor" />
                </svg>
              </span>
              <strong style={{ fontFamily: "var(--font-serif)", fontSize: "1.3rem", color: "var(--bg)" }}>Holibags</strong>
            </div>
            <p style={{ color: "color-mix(in oklab, var(--bg) 70%, white)", maxWidth: 32 + "ch", fontSize: 14 }}>
              Handmade bags, cushions and gifts — sewn on the High Street in Kirkcaldy.
            </p>
          </div>
          <div>
            <h4>Visit</h4>
            <p style={{ fontSize: 14, lineHeight: 1.7, margin: 0 }}>
              305a High Street<br />
              Kirkcaldy<br />
              KY1 1JL
            </p>
          </div>
          <div>
            <h4>Hours</h4>
            <ul style={{ listStyle: "none", padding: 0, margin: 0, fontSize: 14, lineHeight: 1.8 }}>
              {list.map((h) =>
              <li key={h.day} style={{ display: "flex", justifyContent: "space-between", maxWidth: 220 }}>
                  <span>{h.day}</span><span>{h.hours}</span>
                </li>
              )}
            </ul>
          </div>
          <div>
            <h4>Newsletter</h4>
            <p style={{ fontSize: 14, marginBottom: 12, color: "color-mix(in oklab, var(--bg) 70%, white)" }}>
              Workshop dates, new products, and seasonal sewing tips.
            </p>
            <MailingList variant="dark" />
          </div>
        </div>
        <div className="footer-bottom">
          <span>© {new Date().getFullYear()} Holibags. All rights reserved.</span>
          <span style={{ display: "flex", gap: 16 }}>
            {BUSINESS.socials.map((s) =>
            <a key={s.label} href={s.href} target="_blank" rel="noreferrer">{s.label}</a>
            )}
            <a href="#" onClick={(e) => {e.preventDefault();navigate("admin");}} style={{ opacity: 0.6 }}>Admin</a>
          </span>
        </div>
      </div>
    </footer>);

}

// ---- Toast --------------------------------------------------------
function Toast({ message, onDone }) {
  useEffect(() => {
    const t = setTimeout(() => onDone(), 2400);
    return () => clearTimeout(t);
  }, [message]);
  if (!message) return null;
  return <div className="toast" role="status" aria-live="polite">{message}</div>;
}

// ---- Modal --------------------------------------------------------
function Modal({ open, onClose, children }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {if (e.key === "Escape") onClose();};
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [open]);
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose} role="dialog" aria-modal="true">
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ position: "relative" }}>
        <button className="modal-close" onClick={onClose} aria-label="Close">
          <Icon.Close />
        </button>
        {children}
      </div>
    </div>);

}

// ---- Page header --------------------------------------------------
function PageHeader({ eyebrow, title, sub }) {
  return (
    <section className="page-header">
      <div className="container">
        {eyebrow && <div className="eyebrow">{eyebrow}</div>}
        <h1 style={{ marginTop: 8 }}>{title}</h1>
        {sub && <p className="sub">{sub}</p>}
      </div>
    </section>);

}

// ---- Stars --------------------------------------------------------
function Stars({ n = 5 }) {
  return (
    <div className="stars" aria-label={`${n} out of 5 stars`}>
      {"★".repeat(n)}{"☆".repeat(5 - n)}
    </div>);

}

Object.assign(window, { Icon, Brand, Nav, MailingList, Footer, Toast, Modal, PageHeader, Stars, DEFAULT_HOURS });