/* ============================================================
   PURE SPA — AGENDA · primitivos compartidos
   Icon, Button, Tag, Modal, Toast, StatusBadge, inputs, helpers.
   Expone globals en window para los demás scripts babel.
   ============================================================ */
const { useState, useEffect, useRef, useMemo, createContext, useContext } = React;

/* ---- tokens rápidos ---- */
const C = {
  gold: "#C5A143", goldDeep: "#B88A2A", champagne: "#D8C17A", champ30: "rgba(216,193,122,0.3)",
  ivory: "#F8F3EA", ivoryDeep: "#F1E9D9", white: "#FFFFFF", espresso: "#2B2520",
  taupe: "#8C7860", line: "#E8E0D0", gold15: "rgba(197,161,67,0.15)",
};

/* ---- formato ---- */
function clp(n) { return "$" + (n || 0).toLocaleString("es-CL"); }
function fullDate(iso) {
  if (!iso) return "—";
  const [y, m, d] = iso.split("-").map(Number);
  const dd = new Date(y, m - 1, d);
  const dias = ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"];
  const meses = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
  return `${dias[dd.getDay()]} ${d} de ${meses[m - 1]}`;
}
function shortDate(iso) {
  if (!iso) return "—";
  const [y, m, d] = iso.split("-").map(Number);
  const meses = ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"];
  return `${d} ${meses[m - 1]}`;
}
function addMin(t, mins) { const [h, m] = t.split(":").map(Number); const tot = h * 60 + m + mins; return `${String(Math.floor(tot / 60)).padStart(2, "0")}:${String(tot % 60).padStart(2, "0")}`; }
function endTime(start, svc) { return svc ? addMin(start, svc.duration + svc.cleanup) : start; }

/* ---- estados de reserva: etiqueta + colores suaves ---- */
const STATUS = {
  paid:                 { label: "Pagada",        bg: "#E4EFE4", fg: "#3E6B43", dot: "#5C9163" },
  confirmed:            { label: "Confirmada",    bg: "#E2EBF2", fg: "#3A5A78", dot: "#557EA1" },
  pending_payment:      { label: "Pago pendiente",bg: "#F8EFD2", fg: "#8A6A1E", dot: "#C9A53D" },
  pending_confirmation: { label: "Por confirmar", bg: "#F1E9D9", fg: "#8C7860", dot: "#B7A485" },
  completed:            { label: "Completada",    bg: "#E6ECE6", fg: "#5A6B5A", dot: "#7E907E" },
  cancelled:            { label: "Cancelada",     bg: "#EFE7E4", fg: "#9A6B63", dot: "#B98B82" },
  no_show:              { label: "No asistió",    bg: "#F3E0DD", fg: "#9C5048", dot: "#C0726A" },
  blocked:              { label: "Bloqueo",       bg: "#EAE6DF", fg: "#6E6557", dot: "#9A9081" },
};
const PAY_STATUS = {
  paid:      { label: "Pagado",     bg: "#E4EFE4", fg: "#3E6B43" },
  pending:   { label: "Pendiente",  bg: "#F8EFD2", fg: "#8A6A1E" },
  failed:    { label: "Fallido",    bg: "#F3E0DD", fg: "#9C5048" },
  refunded:  { label: "Reembolsado",bg: "#E2EBF2", fg: "#3A5A78" },
  cancelled: { label: "Anulado",    bg: "#EAE6DF", fg: "#6E6557" },
};

/* ---- Icono (Lucide, trazo fino) ---- */
function Icon({ name, size = 20, stroke = 1.5, color = "currentColor", style }) {
  const ref = useRef(null);
  useEffect(() => {
    const lib = window.lucide;
    if (ref.current && lib && lib.icons && lib.icons[name]) {
      ref.current.innerHTML = "";
      const svg = lib.createElement(lib.icons[name]);
      svg.setAttribute("width", size); svg.setAttribute("height", size);
      svg.setAttribute("stroke-width", stroke); svg.setAttribute("stroke", color);
      ref.current.appendChild(svg);
    }
  }, [name, size, stroke, color]);
  return <span ref={ref} style={{ display: "inline-flex", lineHeight: 0, ...style }} />;
}

function Eyebrow({ children, color = C.taupe, style }) {
  return <div style={{ fontFamily: "var(--font-body)", fontSize: 10, fontWeight: 600, letterSpacing: "0.16em",
    textTransform: "uppercase", color, ...style }}>{children}</div>;
}

/* ---- Botón ---- */
function Button({ variant = "primary", children, onClick, style, full, arrow, disabled, type, size = "md" }) {
  const [hover, setHover] = useState(false);
  const pad = size === "sm" ? "9px 18px" : "14px 30px";
  const base = {
    fontFamily: "var(--font-body)", fontSize: size === "sm" ? 10.5 : 11, fontWeight: 600,
    letterSpacing: "0.14em", textTransform: "uppercase", cursor: disabled ? "not-allowed" : "pointer",
    borderRadius: 999, transition: "all .25s ease", border: "none", padding: pad,
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
    width: full ? "100%" : "auto", whiteSpace: "nowrap", opacity: disabled ? 0.4 : 1,
  };
  const variants = {
    primary:   { background: C.gold, color: C.espresso },
    secondary: { background: "transparent", color: C.espresso, border: `1.5px solid ${C.espresso}`, padding: size === "sm" ? "8px 17px" : "12.5px 28px" },
    ghost:     { background: "transparent", color: C.goldDeep, border: `1.5px solid ${C.gold}`, padding: size === "sm" ? "8px 17px" : "12.5px 28px" },
    dark:      { background: C.espresso, color: C.ivory },
    soft:      { background: C.white, color: C.espresso, border: `1px solid ${C.line}`, padding: size === "sm" ? "8px 17px" : "12.5px 28px" },
    danger:    { background: "transparent", color: "#9C5048", border: "1.5px solid #C0726A", padding: size === "sm" ? "8px 17px" : "12.5px 28px" },
  };
  const hov = hover && !disabled ? {
    primary: { background: C.goldDeep }, secondary: { background: C.espresso, color: C.ivory },
    ghost: { background: C.gold, color: C.espresso }, dark: { background: "#3a3228" },
    soft: { borderColor: C.gold, background: C.ivoryDeep }, danger: { background: "#C0726A", color: C.white },
  }[variant] : {};
  return (
    <button type={type || "button"} onClick={disabled ? undefined : onClick}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{ ...base, ...variants[variant], ...hov, ...style }}>
      {children}{arrow && <span style={{ fontSize: 13 }}>→</span>}
    </button>
  );
}

/* ---- Tag / badge ---- */
function Tag({ children, tone = "soft", style }) {
  const tones = {
    soft:  { background: C.ivory, color: C.taupe, border: `1px solid ${C.line}` },
    gold:  { background: C.champagne, color: C.goldDeep },
    dark:  { background: C.espresso, color: C.champagne },
  };
  return <span style={{ display: "inline-flex", alignItems: "center", fontFamily: "var(--font-body)", fontSize: 9.5,
    fontWeight: 600, letterSpacing: "0.1em", textTransform: "uppercase", padding: "5px 11px", borderRadius: 999,
    ...tones[tone], ...style }}>{children}</span>;
}

function StatusBadge({ status, kind = "booking", style }) {
  const map = kind === "pay" ? PAY_STATUS : STATUS;
  const s = map[status] || { label: status, bg: C.ivory, fg: C.taupe };
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "var(--font-body)", fontSize: 10,
      fontWeight: 600, letterSpacing: "0.06em", padding: "5px 11px", borderRadius: 999, background: s.bg, color: s.fg, ...style }}>
      {s.dot && <span style={{ width: 6, height: 6, borderRadius: 999, background: s.dot }} />}{s.label}
    </span>
  );
}

/* ---- Modal / panel lateral ---- */
function Modal({ open, onClose, children, title, eyebrow, side = false, width = 520 }) {
  useEffect(() => {
    if (!open) return;
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 100, background: "rgba(43,37,32,0.42)",
      backdropFilter: "blur(2px)", display: "flex", alignItems: side ? "stretch" : "center",
      justifyContent: side ? "flex-end" : "center", animation: "puFade .25s ease" }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        background: C.ivory, width: side ? "min(460px, 92vw)" : `min(${width}px, 94vw)`,
        maxHeight: side ? "100%" : "92vh", height: side ? "100%" : "auto", overflowY: "auto",
        borderRadius: side ? 0 : 16, boxShadow: "0 24px 80px rgba(43,37,32,0.28)",
        animation: side ? "puSlide .3s cubic-bezier(.4,0,.2,1)" : "puRise .3s cubic-bezier(.4,0,.2,1)" }}>
        <div style={{ position: "sticky", top: 0, zIndex: 2, background: C.ivory, padding: "22px 26px 16px",
          borderBottom: `1px solid ${C.line}`, display: "flex", alignItems: "flex-start", justifyContent: "space-between" }}>
          <div>
            {eyebrow && <Eyebrow color={C.gold} style={{ marginBottom: 6 }}>{eyebrow}</Eyebrow>}
            <div style={{ fontFamily: "var(--font-display)", fontSize: 24, color: C.espresso, lineHeight: 1.1 }}>{title}</div>
          </div>
          <button onClick={onClose} style={{ background: C.white, border: `1px solid ${C.line}`, borderRadius: 999,
            width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer", flexShrink: 0 }}>
            <Icon name="X" size={18} color={C.taupe} />
          </button>
        </div>
        <div style={{ padding: "20px 26px 26px" }}>{children}</div>
      </div>
    </div>
  );
}

/* ---- inputs ---- */
function Field({ label, required, children, hint, error }) {
  return (
    <label style={{ display: "block", marginBottom: 16 }}>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 10.5, fontWeight: 600, letterSpacing: "0.1em",
        textTransform: "uppercase", color: C.taupe, marginBottom: 7 }}>
        {label}{required && <span style={{ color: C.gold }}> *</span>}
      </div>
      {children}
      {error && <div style={{ fontFamily: "var(--font-body)", fontSize: 11, color: "#9C5048", marginTop: 5 }}>{error}</div>}
      {hint && !error && <div style={{ fontFamily: "var(--font-body)", fontSize: 11, color: C.taupe, marginTop: 5 }}>{hint}</div>}
    </label>
  );
}
const inputStyle = {
  width: "100%", fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 300, color: C.espresso,
  background: C.white, border: `1px solid ${C.line}`, borderRadius: 8, padding: "11px 13px", outline: "none",
  transition: "border-color .2s",
};
function Input(props) {
  const [f, setF] = useState(false);
  return <input {...props} style={{ ...inputStyle, borderColor: f ? C.gold : (props.error ? "#C0726A" : C.line), ...props.style }}
    onFocus={(e) => { setF(true); props.onFocus && props.onFocus(e); }}
    onBlur={(e) => { setF(false); props.onBlur && props.onBlur(e); }} />;
}
function Textarea(props) {
  const [f, setF] = useState(false);
  return <textarea {...props} style={{ ...inputStyle, minHeight: 76, resize: "vertical", borderColor: f ? C.gold : C.line, ...props.style }}
    onFocus={() => setF(true)} onBlur={() => setF(false)} />;
}
function Select({ value, onChange, options, placeholder, style }) {
  const [f, setF] = useState(false);
  return (
    <div style={{ position: "relative" }}>
      <select value={value || ""} onChange={(e) => onChange(e.target.value)} onFocus={() => setF(true)} onBlur={() => setF(false)}
        style={{ ...inputStyle, appearance: "none", cursor: "pointer", paddingRight: 34, borderColor: f ? C.gold : C.line, ...style }}>
        {placeholder && <option value="">{placeholder}</option>}
        {options.map((o) => typeof o === "string"
          ? <option key={o} value={o}>{o}</option>
          : <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
      <span style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)", pointerEvents: "none" }}>
        <Icon name="ChevronDown" size={16} color={C.taupe} />
      </span>
    </div>
  );
}

/* ---- Toast ---- */
const ToastCtx = createContext(null);
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = (msg, kind = "ok") => {
    const id = Date.now() + Math.random();
    setToasts((t) => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 3200);
  };
  return (
    <ToastCtx.Provider value={push}>
      {children}
      <div style={{ position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)", zIndex: 200,
        display: "flex", flexDirection: "column", gap: 10, alignItems: "center" }}>
        {toasts.map((t) => (
          <div key={t.id} style={{ display: "flex", alignItems: "center", gap: 10, background: C.espresso,
            color: C.ivory, padding: "13px 20px", borderRadius: 999, boxShadow: "0 12px 40px rgba(43,37,32,0.3)",
            fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 400, animation: "puRise .3s ease" }}>
            <Icon name={t.kind === "ok" ? "Check" : "Info"} size={16} color={C.gold} />{t.msg}
          </div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
}
function useToast() { return useContext(ToastCtx); }

/* ---- divisor de puntos ---- */
function DotDivider({ style }) {
  return <div style={{ textAlign: "center", color: C.champagne, letterSpacing: "0.6em", fontSize: 12, ...style }}>· · ·</div>;
}

Object.assign(window, {
  C, clp, fullDate, shortDate, addMin, endTime, STATUS, PAY_STATUS,
  Icon, Eyebrow, Button, Tag, StatusBadge, Modal, Field, Input, Textarea, Select,
  ToastProvider, useToast, DotDivider,
  useState, useEffect, useRef, useMemo,
});
