// Shared building blocks: skyline strip, speech bubble, instructor card, calendar, etc.
const { useState, useEffect, useRef, useMemo } = React;

// ============ UK + USA LANDMARKS STRIP ============
// Real PNG silhouettes downloaded under CC0 from Wikimedia Commons.
// Files live in assets/landmarks/ so the strip stays intact even if the
// upstream URL ever rots.
const LANDMARKS = [
  { src: "assets/landmarks/big-ben.png",           alt: "Big Ben — London, UK" },
  { src: "assets/landmarks/tower-bridge.png",      alt: "Tower Bridge — London, UK" },
  // Liberty's source PNG is a black silhouette — recolor to brand magenta via mask-image.
  { src: "assets/landmarks/statue-of-liberty.png", alt: "Statue of Liberty — New York, USA",
    tint: "#D946A6", aspect: "600 / 1031" },
  { src: "assets/landmarks/empire-state.png",      alt: "Empire State Building — New York, USA" },
];

function SkylineStrip({ height = 80, className = "", style = {} }) {
  const ground = Math.max(6, Math.round(height * 0.09));
  return (
    <div className={className} style={{
      width: "100%", height, position: "relative",
      display: "flex", alignItems: "flex-end", justifyContent: "space-around",
      gap: 24, padding: "0 32px",
      borderBottom: `${ground}px solid #16335E`,
      ...style,
    }}>
      {LANDMARKS.map((m) => m.tint ? (
        <div key={m.src} role="img" aria-label={m.alt} title={m.alt}
          style={{
            height: "100%", maxWidth: "28%", aspectRatio: m.aspect,
            backgroundColor: m.tint,
            WebkitMaskImage: `url(${m.src})`, maskImage: `url(${m.src})`,
            WebkitMaskRepeat: "no-repeat", maskRepeat: "no-repeat",
            WebkitMaskPosition: "bottom", maskPosition: "bottom",
            WebkitMaskSize: "contain", maskSize: "contain",
            filter: "drop-shadow(0 4px 10px rgba(0,0,0,0.35))",
          }}/>
      ) : (
        <img key={m.src} src={m.src} alt={m.alt} title={m.alt}
          loading="lazy" decoding="async"
          style={{
            height: "100%", width: "auto", maxWidth: "28%",
            objectFit: "contain", objectPosition: "bottom",
            filter: "drop-shadow(0 4px 10px rgba(0,0,0,0.35))",
            display: "block",
          }}/>
      ))}
    </div>
  );
}

// ============ SPEECH BUBBLE (the brand mark element) ============
function SpeechBubble({ children, color = "#FF4D4D", textColor = "#fff", tail = "bl", style = {}, className = "" }) {
  // tail: bl, br, tl, tr
  const tailMap = {
    bl: { left: 24, bottom: -14, rotate: "20deg" },
    br: { right: 24, bottom: -14, rotate: "-20deg" },
    tl: { left: 24, top: -14, rotate: "200deg" },
    tr: { right: 24, top: -14, rotate: "-200deg" },
  };
  const t = tailMap[tail];
  return (
    <div className={className} style={{
      position: "relative", display: "inline-block", padding: "10px 18px",
      background: color, color: textColor, borderRadius: 18, fontWeight: 800,
      ...style,
    }}>
      {children}
      <div style={{
        position: "absolute", width: 22, height: 22, background: color,
        clipPath: "polygon(0 0, 100% 0, 50% 100%)",
        ...t, transform: `rotate(${t.rotate})`,
      }}/>
    </div>
  );
}

// ============ LOGO MARK ============
function LogoMark({ size = 40, withWordmark = true, dark = false }) {
  return (
    <a href="#top" style={{
      display: "inline-flex", alignItems: "center", gap: 10, textDecoration: "none",
      color: dark ? "#fff" : "#0A0A0A",
    }}>
      <img src="assets/logo.png" alt="Speak Up Istanbul"
        style={{ width: size, height: size, borderRadius: "50%", display: "block" }}/>
      {withWordmark && (
        <span className="va-logo-text" style={{ fontFamily: "'Archivo Black', system-ui", fontSize: 16, letterSpacing: -0.3, lineHeight: 1 }}>
          SPEAK UP<br/>
          <span style={{ fontSize: 9, fontWeight: 600, letterSpacing: 2, opacity: 0.7, fontFamily: "Inter" }}>ISTANBUL</span>
        </span>
      )}
    </a>
  );
}

// ============ STRIPED IMAGE PLACEHOLDER ============
function StripedPlaceholder({ label, w = "100%", h = 320, color = "#0A0A0A", bg = "#FFE7CF", style = {}, rotate = 0 }) {
  const id = "stripe-" + Math.random().toString(36).slice(2, 8);
  return (
    <div style={{
      width: w, height: h, position: "relative", overflow: "hidden", borderRadius: 4,
      transform: rotate ? `rotate(${rotate}deg)` : undefined,
      ...style,
    }}>
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0 }}>
        <defs>
          <pattern id={id} patternUnits="userSpaceOnUse" width="14" height="14" patternTransform="rotate(45)">
            <rect width="14" height="14" fill={bg}/>
            <line x1="0" y1="0" x2="0" y2="14" stroke={color} strokeWidth="1.5" opacity="0.18"/>
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#${id})`}/>
      </svg>
      <div style={{
        position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
        fontFamily: "'JetBrains Mono', ui-monospace, monospace", fontSize: 11, color, opacity: 0.65,
        letterSpacing: 1, textTransform: "uppercase", textAlign: "center", padding: 12,
      }}>
        [ {label} ]
      </div>
    </div>
  );
}

// ============ INSTRUCTOR AVATAR (geometric portrait abstraction with photo placeholder) ============
function InstructorAvatar({ teacher, size = 220, style = {} }) {
  return (
    <div style={{
      width: size, height: size, position: "relative", overflow: "hidden",
      background: teacher.color, ...style,
    }}>
      {/* Striped backdrop */}
      <svg width="100%" height="100%" style={{ position: "absolute", inset: 0, opacity: 0.18 }}>
        <defs>
          <pattern id={`av-${teacher.name}`} patternUnits="userSpaceOnUse" width="10" height="10" patternTransform="rotate(45)">
            <rect width="10" height="10" fill="transparent"/>
            <line x1="0" y1="0" x2="0" y2="10" stroke="#000" strokeWidth="1.5"/>
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#av-${teacher.name})`}/>
      </svg>
      {/* Big initials */}
      <div style={{
        position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
        fontFamily: "'Archivo Black', system-ui",
        fontSize: typeof size === "number" ? size * 0.5 : "min(50%, 96px)",
        color: "#fff",
        mixBlendMode: "normal", letterSpacing: -2,
      }}>
        {teacher.initials}
      </div>
      {/* Flag corner */}
      <div style={{
        position: "absolute", top: 10, right: 10, fontSize: 22,
        background: "#fff", padding: "4px 8px", borderRadius: 999,
        boxShadow: "0 2px 6px rgba(0,0,0,0.2)",
      }}>{teacher.flag}</div>
    </div>
  );
}

// ============ MINI VIDEO-CALL MOCK (for hero) ============
function VideoCallMock({ teacher, style = {}, density = "comfortable", image }) {
  return (
    <div style={{
      background: "#0A0A0A", borderRadius: 18, padding: 14, color: "#fff",
      boxShadow: "0 24px 60px rgba(0,0,0,0.25), 0 4px 12px rgba(0,0,0,0.1)",
      position: "relative", ...style,
    }}>
      {/* Window chrome */}
      <div style={{ display: "flex", gap: 6, marginBottom: 10 }}>
        <span style={{ width: 10, height: 10, borderRadius: 999, background: "#FF4D4D" }}/>
        <span style={{ width: 10, height: 10, borderRadius: 999, background: "#F4B92E" }}/>
        <span style={{ width: 10, height: 10, borderRadius: 999, background: "#1FB6B0" }}/>
        <span style={{ marginLeft: "auto", fontSize: 10, opacity: 0.5, fontFamily: "monospace" }}>● live · 24:18</span>
      </div>
      {/* Video tile */}
      <div style={{ position: "relative", borderRadius: 10, overflow: "hidden", aspectRatio: "16/10" }}>
        {image ? (
          <img src={image} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}/>
        ) : (
          <InstructorAvatar teacher={teacher} size="100%" style={{ width: "100%", height: "100%" }}/>
        )}
        {!image && (
          <>
            {/* Self preview */}
            <div style={{
              position: "absolute", bottom: 10, right: 10, width: "26%", aspectRatio: "16/10",
              background: "#FFE7CF", borderRadius: 6, border: "2px solid #fff",
              display: "flex", alignItems: "center", justifyContent: "center",
              fontFamily: "monospace", fontSize: 9, color: "#0A0A0A", opacity: 0.9,
            }}>
              [ you ]
            </div>
            {/* Caption */}
            <div style={{
              position: "absolute", bottom: 10, left: 10,
              background: "rgba(0,0,0,0.7)", padding: "6px 10px", borderRadius: 6,
              fontSize: 11, fontWeight: 500,
            }}>
              {teacher.name}, {teacher.origin} {teacher.flag}
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// ============ DENSITY HELPERS ============
const DENSITY = {
  compact:    { sec: 64,  gap: 24, h1: 1.0, body: 1.0 },
  comfortable:{ sec: 110, gap: 36, h1: 1.0, body: 1.0 },
  spacious:   { sec: 160, gap: 48, h1: 1.05, body: 1.05 },
};

// ============ INTERACTIVE CALENDAR ============
function MiniCalendar({ value, onChange, accent = "#FF4D4D" }) {
  const today = new Date();
  const [month, setMonth] = useState(today.getMonth());
  const [year, setYear] = useState(today.getFullYear());
  const first = new Date(year, month, 1).getDay();
  const offset = first === 0 ? 6 : first - 1; // Mon-first
  const dim = new Date(year, month + 1, 0).getDate();
  const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
  const monthsTr = ["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"];
  const lang = (typeof window !== "undefined" && window.__activeLang) || "en";
  const monthNames = lang === "tr" ? monthsTr : months;
  const dows = lang === "tr" ? ["Pt","Sa","Ça","Pe","Cu","Ct","Pz"] : ["Mo","Tu","We","Th","Fr","Sa","Su"];

  const cells = [];
  for (let i = 0; i < offset; i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(d);
  while (cells.length % 7) cells.push(null);

  const isPast = (d) => {
    if (!d) return true;
    const dt = new Date(year, month, d);
    const t = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    return dt < t;
  };

  return (
    <div style={{ background: "#fff", color: "#0A0A0A", borderRadius: 14, padding: 16, fontFamily: "Inter" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <button onClick={() => {
          const m = month - 1;
          if (m < 0) { setMonth(11); setYear(year - 1); } else setMonth(m);
        }} style={navBtn}>‹</button>
        <span style={{ fontWeight: 700, fontSize: 14 }}>{monthNames[month]} {year}</span>
        <button onClick={() => {
          const m = month + 1;
          if (m > 11) { setMonth(0); setYear(year + 1); } else setMonth(m);
        }} style={navBtn}>›</button>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 4, fontSize: 10, color: "#888", textAlign: "center", marginBottom: 6 }}>
        {dows.map(d => <div key={d}>{d}</div>)}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 4 }}>
        {cells.map((d, i) => {
          if (!d) return <div key={i}/>;
          const past = isPast(d);
          const selDate = value ? new Date(value) : null;
          const isSel = selDate && selDate.getDate() === d && selDate.getMonth() === month && selDate.getFullYear() === year;
          return (
            <button key={i}
              disabled={past}
              onClick={() => onChange(new Date(year, month, d).toISOString())}
              style={{
                aspectRatio: "1", border: "none", borderRadius: 8, cursor: past ? "not-allowed" : "pointer",
                background: isSel ? accent : (past ? "transparent" : "#F5F5F5"),
                color: isSel ? "#fff" : (past ? "#CCC" : "#0A0A0A"),
                fontWeight: isSel ? 800 : 500, fontSize: 13,
                transition: "transform 0.15s",
              }}
              onMouseEnter={(e) => !past && !isSel && (e.currentTarget.style.background = "#0A0A0A", e.currentTarget.style.color = "#fff")}
              onMouseLeave={(e) => !past && !isSel && (e.currentTarget.style.background = "#F5F5F5", e.currentTarget.style.color = "#0A0A0A")}
            >{d}</button>
          );
        })}
      </div>
    </div>
  );
}
const navBtn = {
  width: 28, height: 28, border: "1px solid #EEE", background: "#fff", borderRadius: 8,
  cursor: "pointer", fontSize: 16, display: "flex", alignItems: "center", justifyContent: "center",
};

// ============ TIME SLOTS ============
function TimeSlots({ date, value, onChange, accent = "#FF4D4D" }) {
  const slots = ["09:00","10:30","12:00","14:00","15:30","17:00","18:30","20:00"];
  // disable a couple deterministically based on date
  const disabledFor = (d) => {
    if (!d) return new Set();
    const dt = new Date(d).getDate();
    return new Set(slots.filter((_, i) => (dt + i) % 5 === 0));
  };
  const dis = disabledFor(date);
  return (
    <div className="va-time-slots" style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8 }}>
      {slots.map(s => {
        const off = dis.has(s);
        const sel = value === s;
        return (
          <button key={s} onClick={() => !off && onChange(s)} disabled={off}
            style={{
              padding: "10px 6px", border: "none", borderRadius: 8, cursor: off ? "not-allowed" : "pointer",
              background: sel ? accent : (off ? "#FAFAFA" : "#F5F5F5"),
              color: sel ? "#fff" : (off ? "#CCC" : "#0A0A0A"),
              fontWeight: sel ? 800 : 600, fontSize: 13, fontFamily: "Inter",
              textDecoration: off ? "line-through" : "none",
            }}>{s}</button>
        );
      })}
    </div>
  );
}

// ============ FORM HELPERS ============
function useBookingForm() {
  const [step, setStep] = useState(1);
  const [date, setDate] = useState(null);
  const [time, setTime] = useState(null);
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [phone, setPhone] = useState("");
  const [goal, setGoal] = useState("");
  const [errors, setErrors] = useState({});
  const [done, setDone] = useState(false);

  const validate = () => {
    const e = {};
    if (!name.trim()) e.name = true;
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = true;
    if (!/^[+\d\s()-]{7,}$/.test(phone)) e.phone = true;
    setErrors(e);
    return Object.keys(e).length === 0;
  };
  return { step, setStep, date, setDate, time, setTime, name, setName, email, setEmail, phone, setPhone, goal, setGoal, errors, validate, done, setDone };
}

// ============ PARALLAX HOOK ============
function useScrollY(scopeRef) {
  const [y, setY] = useState(0);
  useEffect(() => {
    const target = scopeRef?.current || window;
    const get = () => scopeRef?.current ? scopeRef.current.scrollTop : window.scrollY;
    const onScroll = () => setY(get());
    target.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => target.removeEventListener("scroll", onScroll);
  }, [scopeRef]);
  return y;
}

window.SkylineStrip = SkylineStrip;
window.SpeechBubble = SpeechBubble;
window.LogoMark = LogoMark;
window.StripedPlaceholder = StripedPlaceholder;
window.InstructorAvatar = InstructorAvatar;
window.VideoCallMock = VideoCallMock;
window.MiniCalendar = MiniCalendar;
window.TimeSlots = TimeSlots;
window.useBookingForm = useBookingForm;
window.useScrollY = useScrollY;
window.DENSITY = DENSITY;
