/* Precitaville UI kit — v2 components (Heath-shelf identity) */

const { useState } = React;

/* ---------------- Nav ---------------- */
function Nav({ page, onNavigate }) {
  const [menuOpen, setMenuOpen] = useState(false);
  const items = [
    { id: "home",      label: "Home" },
    { id: "newsevents", label: "News & Events" },
    { id: "neighbors", label: "Neighbors" },
    { id: "fund",      label: "The Fund" },
  ];
  const navigate = (id) => { setMenuOpen(false); onNavigate(id); };
  return (
    <nav className="nav">
      <div className="wrap nav-inner">
        <a href="#" className="word" onClick={(e) => { e.preventDefault(); navigate("home"); }}>
          Precita<em>ville</em>
        </a>
        <ul className="nav-links">
          {items.map((i) => (
            <li key={i.id}>
              <a
                href="#"
                className={page === i.id ? "active" : ""}
                onClick={(e) => { e.preventDefault(); navigate(i.id); }}
              >
                {i.label}
              </a>
            </li>
          ))}
        </ul>
        <button className="btn nav-cta" onClick={() => navigate("join")}>Join us</button>
        <button
          className="nav-burger"
          aria-label={menuOpen ? "Close menu" : "Open menu"}
          aria-expanded={menuOpen}
          onClick={() => setMenuOpen(!menuOpen)}
        >
          <span className="nav-burger-line" />
          <span className="nav-burger-line" />
          <span className="nav-burger-line" />
        </button>
      </div>
      {menuOpen && (
        <div className="nav-mobile-menu">
          <ul className="nav-mobile-links">
            {items.map((i) => (
              <li key={i.id}>
                <a
                  href="#"
                  className={page === i.id ? "active" : ""}
                  onClick={(e) => { e.preventDefault(); navigate(i.id); }}
                >
                  {i.label}
                </a>
              </li>
            ))}
            <li className="nav-mobile-cta">
              <button className="btn" onClick={() => navigate("join")}>Join us →</button>
            </li>
          </ul>
        </div>
      )}
    </nav>
  );
}

/* ---------------- Park map — mosaic edition ---------------- */
function ParkMap({ mapId = "main" }) {
  // Brand palette, heavily weighted toward greens (85%) with accent pops (15%)
  const palette = [
    '#5C6A38','#9FA46E','#5C6A38','#7A8B4A','#5C6A38','#9FA46E',
    '#5C6A38','#5C6A38','#9FA46E','#5C6A38','#B8503A','#5C6A38',
    '#9FA46E','#5C6A38','#C49838','#5C6A38','#9FA46E','#3D788C',
    '#5C6A38','#9FA46E'
  ];

  // Generate mosaic tile grid — clip path removes tiles outside the park polygon
  const tiles = [];
  for (let c = 0; c < 32; c++) {
    for (let r = 0; r < 10; r++) {
      tiles.push({
        x: 86 + c * 10.5,
        y: 188 + r * 10.5,
        color: palette[(c * 7 + r * 3 + c % 5 + r % 3) % palette.length]
      });
    }
  }

  // Precita Park: elongated E-W strip (Folsom → Alabama, south edge = Precita Ave)
  // Real proportions: ~4.3:1 (long thin parallelogram, very slightly angled)
  const clipId = "parkClip_" + mapId;
  const parkPts = "88,272 92,196 382,190 390,272";

  const nsLabels = [
    { x: 85,  label: 'FOLSOM' },
    { x: 216, label: 'TREAT' },
    { x: 386, label: 'ALABAMA' },
    { x: 441, label: 'FLORIDA' },
  ];

  return (
    <div className="park-map">
      <svg viewBox="0 0 480 528" xmlns="http://www.w3.org/2000/svg" style={{ width: '100%', height: '100%', display: 'block' }}>
        <defs>
          <clipPath id={clipId}><polygon points={parkPts}/></clipPath>
        </defs>

        {/* ── Paper background ── */}
        <rect width="480" height="528" fill="#F2EDE6"/>

        {/* ── E-W streets ── */}
        <rect x="0"   y="68"  width="480" height="22" fill="#DDD5C8"/> {/* Cesar Chavez */}
        <rect x="0"   y="20"  width="480" height="10" fill="#E5E0DA"/> {/* 26th St */}
        <rect x="64"  y="272" width="400" height="14" fill="#DDD5C8"/> {/* Precita Ave */}
        <rect x="0"   y="344" width="480" height="10" fill="#E5E0DA"/>
        <rect x="0"   y="402" width="480" height="9"  fill="#E5E0DA"/>
        <rect x="0"   y="460" width="480" height="8"  fill="#E5E0DA"/>

        {/* ── N-S streets ── */}
        <rect x="50"  y="0"  width="11" height="528" fill="#E5E0DA"/> {/* Shotwell */}
        <rect x="78"  y="0"  width="14" height="528" fill="#DDD5C8"/> {/* Folsom */}
        <rect x="210" y="0"  width="13" height="528" fill="#DDD5C8"/> {/* Treat Ave */}
        <rect x="272" y="90" width="12" height="438" fill="#E5E0DA"/> {/* Harrison */}
        <rect x="378" y="0"  width="14" height="528" fill="#DDD5C8"/> {/* Alabama */}
        <rect x="435" y="0"  width="12" height="528" fill="#E5E0DA"/> {/* Florida */}

        {/* ── Diagonal streets (characteristic Bernal/Mission non-grid) ── */}
        <line x1="86" y1="286" x2="8"  y2="468" stroke="#DDD5C8" strokeWidth="12" strokeLinecap="round"/>
        <line x1="86" y1="286" x2="38" y2="392" stroke="#E5E0DA" strokeWidth="9"  strokeLinecap="round"/>

        {/* ── Mosaic tiles, clipped to park polygon ── */}
        <g clipPath={`url(#${clipId})`}>
          {tiles.map((t, i) => (
            <rect key={i} x={t.x} y={t.y} width="9" height="9" fill={t.color} rx="0.8"/>
          ))}
        </g>

        {/* ── Park boundary outline ── */}
        <polygon points={parkPts} fill="none" stroke="#364520" strokeWidth="1.5" strokeLinejoin="round"/>

        {/* ── Street labels: E-W ── */}
        <text x="240" y="83" textAnchor="middle" fontFamily="Manrope,sans-serif" fontSize="8.5" fontWeight="700" letterSpacing="1.5" fill="#8A8078">CESAR CHAVEZ ST</text>
        <text x="218" y="284" textAnchor="middle" fontFamily="Manrope,sans-serif" fontSize="8" fontWeight="700" letterSpacing="1.3" fill="#8A8078">PRECITA AVE</text>

        {/* ── Street labels: N-S (rotated, placed in block between C.Chavez and park) ── */}
        {nsLabels.map(({ x, label }) => (
          <text key={x} x={x} y={136} textAnchor="middle"
            fontFamily="Manrope,sans-serif" fontSize="7.5" fontWeight="700"
            letterSpacing="1.2" fill="#8A8078"
            transform={`rotate(-90 ${x} 136)`}>{label}</text>
        ))}

        {/* ── Park name ── */}
        <text x="238" y="234" textAnchor="middle"
          fontFamily="Newsreader,Georgia,serif" fontSize="17" fontWeight="400"
          fontStyle="italic" fill="rgba(255,252,242,0.95)">Precita Park</text>

        {/* ── Bandshell marker ── */}
        <circle cx="136" cy="216" r="5" fill="#C49838" stroke="rgba(255,250,236,0.9)" strokeWidth="1.5"/>
        <text x="146" y="214" fontFamily="Manrope,sans-serif" fontSize="7" fontWeight="700"
          letterSpacing="0.8" fill="rgba(255,250,236,0.88)">BANDSHELL</text>

        {/* ── Butterfly garden indicator ── */}
        <ellipse cx="320" cy="238" rx="26" ry="13" fill="none"
          stroke="rgba(255,252,238,0.38)" strokeWidth="1" strokeDasharray="3,2.5"/>
        <text x="320" y="254" textAnchor="middle" fontFamily="Manrope,sans-serif"
          fontSize="6.5" fontWeight="700" letterSpacing="0.8"
          fill="rgba(255,250,236,0.52)">BUTTERFLY GARDEN</text>

        {/* ── North arrow ── */}
        <g transform="translate(450,492)">
          <circle r="18" fill="rgba(238,233,225,0.94)" stroke="#BFB5A8" strokeWidth="1"/>
          <text y="-3" textAnchor="middle" fontFamily="Manrope,sans-serif" fontSize="10" fontWeight="800" fill="#433E38">N</text>
          <line y1="1" y2="10" stroke="#433E38" strokeWidth="1.5"/>
          <polygon points="0,1 -3,9 0,7 3,9" fill="#433E38"/>
        </g>

        {/* ── Byline ── */}
        <text x="240" y="519" textAnchor="middle"
          fontFamily="Manrope,sans-serif" fontSize="8" fontWeight="700"
          letterSpacing="2" fill="#A89E96">PRECITAVILLE · BERNAL HEIGHTS · SF</text>
      </svg>
    </div>
  );
}

/* ---------------- Mission pillars ---------------- */
function MissionPillars({ onFund, onOrganize, onConnect }) {
  const pillars = [
    { glaze: "clay",    icon: "↗", title: "Organize",    body: "Block parties, plant swaps, film nights, tree plantings, and the Sunday jazz jam in Precita Park. We run the events that make this block worth living on.", action: onOrganize },
    { glaze: "moss",    icon: "◆", title: "Invest",      body: "The Precitaville Fund channels neighbor contributions into lasting improvements — park infrastructure, street trees, lighting, and small grants for local programs.", action: onFund },
    { glaze: "pacific", icon: "○", title: "Connect",     body: "We're building the connective tissue of the north slope — mapping the leaders, the activists, the block captains, and the businesses who make change happen.", action: onConnect },
  ];
  return (
    <div className="mission-strip">
      <div className="wrap">
        <div className="mission-pillars">
          {pillars.map((p) => (
            <div key={p.title} className="mission-pillar" style={{ borderLeft: p === pillars[0] ? "none" : "1px solid var(--hair)" }}>
              <div className="pillar-icon" style={{ background: `var(--${p.glaze})`, color: "var(--snow)" }}>{p.icon}</div>
              <h4>{p.title}</h4>
              <p>{p.body}</p>
              {p.action && <button className="btn secondary" style={{ width: "max-content", marginTop: 8 }} onClick={p.action}>Learn more →</button>}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ---------------- Hero ---------------- */
function Hero({ onPrimary, onSecondary, onFund, onOrganize, onConnect }) {
  return (
    <>
      <header className="hero">
        <div className="wrap hero-inner">
          <div>
            <div className="hero-identity">● Neighborhood association · Est. 2026</div>
            <h1 className="hero-title">
              Organizing<br />
              the north slope <em>of Bernal.</em>
            </h1>
            <p className="hero-lede">
              Precitaville is the pocket of San Francisco below the hill, around Precita Park. We run events, invest in improvements, and connect the neighbors who want to make this block better.
            </p>
            <div className="hero-actions">
              <button className="btn" onClick={onPrimary}>See what's on this week →</button>
            </div>
          </div>
          <ParkMap />
        </div>
      </header>
      <MissionPillars onFund={onFund} onOrganize={onOrganize} onConnect={onConnect} />
    </>
  );
}

/* ---------------- Event card ---------------- */
function EventCard({ ev, featured, onClick }) {
  const cls = "event-card" + (featured ? " featured" : "");
  return (
    <a href="#" className={cls} onClick={(e) => { e.preventDefault(); onClick && onClick(ev); }}>
      <div className={"glaze-block glaze-" + ev.glaze}>
        <div className="day-of-week">{ev.dow}</div>
        <div className="day-num">{ev.day}</div>
        <div className="month">{ev.mon} · {ev.time}</div>
      </div>
      <div className="body">
        <div className="eyebrow">{ev.kind} · {ev.place}</div>
        <h3>{ev.title}</h3>
        <p>{ev.blurb}</p>
      </div>
    </a>
  );
}

/* ---------------- Blog card ---------------- */
function BlogCard({ post, onClick }) {
  return (
    <a href="#" className="blog-card" onClick={(e) => { e.preventDefault(); onClick && onClick(post); }}>
      <div className="img" />
      <div className="body">
        <div className="byline">{post.cat} · {post.date}</div>
        <h4>{post.title}</h4>
        <p>{post.excerpt}</p>
      </div>
    </a>
  );
}

/* ---------------- Masthead announcement (indigo block) ---------------- */
function Masthead({ onClick }) {
  return (
    <section className="masthead">
      <div className="wrap masthead-inner">
        <div>
          <div className="eyebrow">A note from the neighbors</div>
          <h2>Help us lower the speed limit <em>on Precita Avenue.</em></h2>
          <p>SFMTA holds a public hearing on June 5. It takes thirty seconds to email — and these things only happen with community support. We've drafted the note for you.</p>
        </div>
        <div style={{ textAlign: "right" }}>
          <button className="btn" onClick={onClick}>Send the email →</button>
        </div>
      </div>
    </section>
  );
}

/* ---------------- Newsletter ---------------- */
function Newsletter() {
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [done, setDone] = useState(false);
  const submit = (e) => { e.preventDefault(); if (email) setDone(true); };
  return (
    <section className="newsletter">
      <div className="wrap newsletter-inner">
        <div>
          <div className="eyebrow" style={{ color: "var(--clay-d)" }}>The Precita Post · a monthly dispatch</div>
          <h2 style={{ marginTop: 12 }}>A letter to the<br/>block, <em>in your inbox.</em></h2>
          <p>One email a month. Events, openings, the occasional coyote sighting. You can stop it any time.</p>
        </div>
        <div>
          {done ? (
            <div className="newsletter-form">
              <div className="eyebrow" style={{ color: "var(--moss-d)" }}>Thanks, neighbor</div>
              <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 400, fontSize: 28, margin: "8px 0 8px", lineHeight: 1.1 }}>You're on the list.</h3>
              <p style={{ margin: 0, color: "var(--charcoal)" }}>First dispatch goes out next Friday. Welcome.</p>
            </div>
          ) : (
            <form onSubmit={submit} className="newsletter-form" style={{ display: "flex", flexDirection: "column", gap: 18 }}>
              <div className="field"><label>Your name</label><input value={name} onChange={(e) => setName(e.target.value)} placeholder="Jessica from Bonview St." /></div>
              <div className="field"><label>Email</label><input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@neighborly.email" /></div>
              <div style={{ display: "flex", gap: 16, alignItems: "center", marginTop: 4 }}>
                <button type="submit" className="btn">Sign me up →</button>
                <span className="fine">No spam, no list-selling.</span>
              </div>
            </form>
          )}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Footer ---------------- */
function Footer() {
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-grid">
          <div>
            <div className="word">Precita<em>ville</em></div>
            <p style={{ color: "rgba(255,255,255,0.7)", maxWidth: "42ch", fontSize: 14.5, marginTop: 14, lineHeight: 1.55 }}>
              A neighborhood association for the north slope of Bernal Heights, around Precita Park. Run by neighbors, for neighbors. Loosely incorporated, loosely on time.
            </p>
            <div className="eyebrow" style={{ marginTop: 18, color: "var(--aqua)" }}>Est. 2026 · San Francisco</div>
          </div>
          <div>
            <h5>Get involved</h5>
            <ul>
              <li><a href="#">Events calendar</a></li>
              <li><a href="#">Volunteer</a></li>
              <li><a href="#">Plant swap</a></li>
              <li><a href="#">Block party</a></li>
            </ul>
          </div>
          <div>
            <h5>Read</h5>
            <ul>
              <li><a href="#">The Precita Post</a></li>
              <li><a href="#">Blog archive</a></li>
              <li><a href="#">2025 community survey</a></li>
              <li><a href="#">Coyote sightings</a></li>
            </ul>
          </div>
          <div>
            <h5>Follow along</h5>
            <ul>
              <li><a href="#">Instagram</a></li>
              <li><a href="#">Bluesky</a></li>
              <li><a href="#">Newsletter</a></li>
              <li><a href="mailto:hi@precitaville.org">hi@precitaville.org</a></li>
            </ul>
          </div>
        </div>
        <div className="fine">
          <span>© 2026 Friends of Precitaville · A 501(c)(3) in waiting</span>
          <span>Built by neighbors on a foggy Sunday</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------------- Join modal ---------------- */
function JoinModal({ open, onClose }) {
  if (!open) return null;
  return (
    <div className="modal-veil" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="close" onClick={onClose} aria-label="Close">×</button>
        <div className="eyebrow" style={{ color: "var(--clay-d)", marginBottom: 8 }}>Hello, neighbor</div>
        <h2>Join the list.</h2>
        <p style={{ color: "var(--charcoal)", fontSize: 16, marginBottom: 24, lineHeight: 1.5 }}>
          We'll send a friendly note when there's an event, a vote, or a coyote sighting worth sharing. About one a month. That's it.
        </p>
        <form onSubmit={(e) => { e.preventDefault(); onClose(); }} style={{ display: "flex", flexDirection: "column", gap: 18 }}>
          <div className="field"><label>Name</label><input placeholder="Your name" autoFocus /></div>
          <div className="field"><label>Email</label><input type="email" placeholder="you@neighborly.email" required /></div>
          <div className="field"><label>Block (optional)</label><input placeholder="e.g. Bonview St., Precita Ave., Folsom" /></div>
          <button type="submit" className="btn" style={{ marginTop: 8 }}>Sign me up →</button>
        </form>
      </div>
    </div>
  );
}

/* ---------------- RSVP modal ---------------- */
function RsvpModal({ ev, onClose }) {
  const [done, setDone] = useState(false);
  if (!ev) return null;
  return (
    <div className="modal-veil" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="close" onClick={onClose} aria-label="Close">×</button>
        {done ? (
          <>
            <div className="eyebrow" style={{ color: "var(--moss-d)", marginBottom: 8 }}>You're in</div>
            <h2>See you {ev.dow.toLowerCase()}.</h2>
            <p style={{ color: "var(--charcoal)", fontSize: 17, marginBottom: 24, lineHeight: 1.5 }}>
              {ev.title} · {ev.mon} {ev.day}, {ev.time} · {ev.place}.<br/>
              We've sent a calendar invite. Bring a folding chair.
            </p>
            <button className="btn secondary" onClick={onClose}>Close</button>
          </>
        ) : (
          <>
            <div className="eyebrow" style={{ color: "var(--clay-d)", marginBottom: 8 }}>RSVP</div>
            <h2>{ev.title}</h2>
            <p style={{ color: "var(--charcoal)", fontSize: 16, marginBottom: 20 }}>{ev.mon} {ev.day} · {ev.time} · {ev.place}</p>
            <form onSubmit={(e) => { e.preventDefault(); setDone(true); }} style={{ display: "flex", flexDirection: "column", gap: 18 }}>
              <div className="field"><label>Name</label><input autoFocus placeholder="Your name" required /></div>
              <div className="field"><label>Email</label><input type="email" placeholder="you@neighborly.email" required /></div>
              <div className="field"><label>How many of you?</label><input type="number" defaultValue="1" min="1" max="20" /></div>
              <button type="submit" className="btn" style={{ marginTop: 8 }}>Count me in →</button>
            </form>
          </>
        )}
      </div>
    </div>
  );
}

/* expose */
Object.assign(window, { Nav, Hero, EventCard, BlogCard, Masthead, Newsletter, Footer, JoinModal, RsvpModal, ParkMap, MissionPillars });
