/* Shared data + hooks used by all three variants.
   Each variant skins the same content & chatbot logic in its own visual language. */

const { useState, useEffect, useRef, useCallback, useMemo } = React;

/* -------------------------------------------------------------------------- */
/* Site content — placeholder-driven, edit freely.                            */
/* -------------------------------------------------------------------------- */

const SITE = {
  name: "Lucas Rollo",
  tagline: "Pick my brain.",
  nav: ["Home", "Work", "Writing"],

  contact: {
    linkedin: "https://www.linkedin.com/in/lucasrollo/",
    email: "hello@example.com",
  },

  projects: [
    {
      slug: "project-one",
      title: "[Project One]",
      year: "2025",
      role: "PM · 0→1",
      blurb: "[One-sentence what-and-why. Specific. Avoid \"led cross-functional team\" energy.]",
    },
    {
      slug: "project-two",
      title: "[Project Two]",
      year: "2024",
      role: "PM",
      blurb: "[A real outcome, a real number, a real surprise.]",
    },
    {
      slug: "project-three",
      title: "[Project Three]",
      year: "2023",
      role: "PM · launch",
      blurb: "[What you changed your mind about while building it.]",
    },
    {
      slug: "project-four",
      title: "[Project Four]",
      year: "2022",
      role: "PM",
      blurb: "[One line. Save the depth for the bot.]",
    },
  ],

  workHistory: [
    { company: "Moveworks", note: "Acquired by ServiceNow", title: "Senior Product Manager", years: "2022 — 2026" },
    { company: "Integrative Ventures", title: "Product Manager", years: "2021" },
    { company: "Qualcomm", title: "Software Engineer", years: "2020" },
  ],

  recommendations: [
    {
      quote: "[A short quote from a colleague — two or three sentences about how they experienced working with you. Specific beats glowing.]",
      name: "[Colleague Name]",
      relation: "[Engineering Lead, Company Two]",
    },
    {
      quote: "[Another quote — different angle, different voice. Maybe a designer or a manager. Keep them concrete.]",
      name: "[Colleague Name]",
      relation: "[Design Director, Company One]",
    },
    {
      quote: "[A third quote — perhaps a direct report or cross-functional partner. The variety is what makes this section feel real.]",
      name: "[Colleague Name]",
      relation: "[Staff Engineer, Company Three]",
    },
  ],

  writing: [
    {
      slug: "on-craft",
      title: "[On craft, and why it's not the same as polish]",
      date: "2026-04-22",
      kind: "essay",
      blurb: "[A one-line description of the piece — what it argues, who it's for.]",
      body: [
        "[Opening paragraph — set the scene. What were you thinking about when you started writing this? Make it specific.]",
        "[Middle — the actual argument or observation. A few paragraphs is plenty. Resist the urge to be comprehensive.]",
        "[Close — leave the reader with a question or an image, not a conclusion. Short.]",
      ],
    },
    {
      slug: "small-thought-on-meetings",
      title: "[A small thought on meetings]",
      date: "2026-03-14",
      kind: "note",
      blurb: "[Optional one-liner.]",
      body: [
        "[Short take — two or three paragraphs at most. The kind of thing you'd text a coworker.]",
        "[Land it. Move on.]",
      ],
    },
    {
      slug: "what-i-learned-shipping",
      title: "[What I learned shipping {something}]",
      date: "2026-02-02",
      kind: "essay",
      blurb: "[Specific lessons from a specific project. Numbers help.]",
      body: [
        "[Set the project up in one paragraph — what it was, what was at stake.]",
        "[The thing you got wrong. Be honest. This is the part people remember.]",
        "[What you'd do differently. End there.]",
      ],
    },
    {
      slug: "on-taste",
      title: "[On taste as a PM skill]",
      date: "2026-01-09",
      kind: "note",
      blurb: "",
      body: [
        "[Two paragraphs on why taste matters more than frameworks. Or whatever your real take is.]",
        "[Leave room for a follow-up post.]",
      ],
    },
    {
      slug: "reading-2025",
      title: "[What I read in 2025]",
      date: "2025-12-30",
      kind: "essay",
      blurb: "[Books, papers, essays. Annotated.]",
      body: [
        "[A short intro about how the year went, reading-wise.]",
        "[Then the list — title, author, one sentence of reaction. No star ratings.]",
      ],
    },
  ],
};

const PROSE_DATE = (iso) => {
  const d = new Date(iso + "T00:00:00");
  return d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
};

const SHORT_DATE = (iso) => {
  const d = new Date(iso + "T00:00:00");
  return d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "2-digit" });
};

/* -------------------------------------------------------------------------- */
/* Chatbot hook                                                                */
/* -------------------------------------------------------------------------- */

function getSystemPrompt() {
  const instructions = document.getElementById("chatbot-system-prompt");
  const base = instructions ? instructions.textContent.trim() : "";

  const info = window.BASIC_INFO || {};
  const resume = window.RESUME || {};

  const basicInfoSection = info.name ? `
— Basic Info —
Name: ${info.name}
Location: ${info.location}
Background: ${info.background}
Professional interests: ${info.interests?.professional || ""}
Personal interests: ${info.interests?.personal || ""}
Values: ${(info.values || []).join(" | ")}
Working style: ${info.workingStyle}
Communication style: ${info.communicationStyle || ""}
What Lucas is NOT: ${info.whatLucasIsNot || ""}
Fun facts: ${(info.funFacts || []).join(" | ")}`.trim() : "";

  const workSection = (resume.experience || []).length ? `
— Work History —
${resume.experience.map(e => {
  const context = [e.what_you_owned, e.what_you_worked_on, e.what_you_built].filter(Boolean).join(" ");
  const rolesText = (e.roles || []).map(r => {
    const highlights = (r.highlights || []).map(h => `    • ${h}`).join("\n");
    return `  ${r.title} (${r.start}–${r.end})${highlights ? "\n" + highlights : ""}`;
  }).join("\n");
  return `${e.company}${context ? "\n  " + context : ""}${rolesText ? "\n" + rolesText : ""}`;
}).join("\n\n")}`.trim() : "";

  const educationSection = (resume.education || []).length ? `
— Education —
${resume.education.map(e => `${e.school} — ${e.degree}, ${e.graduated || e.year}`).join("\n")}`.trim() : "";

  const skillsSection = (resume.skills || []).length ? `
— Skills —
${resume.skills.join(", ")}`.trim() : "";

  const awardsSection = (resume.awards || []).length ? `
— Awards & Recognition —
${resume.awards.map(a => `${a.title} (${a.date}): ${a.description}`).join("\n")}`.trim() : "";

  const storiesSection = (window.STORIES || []).length ? `
— Professional Stories —
${window.STORIES.map(s => `${s.title}:\n  ${s.body}`).join("\n\n")}`.trim() : "";

  const projectsSection = SITE.projects.filter(p => !p.title.startsWith("[")).length ? `
— Projects —
${SITE.projects.filter(p => !p.title.startsWith("[")).map(p => `${p.title} (${p.year}, ${p.role}): ${p.blurb}`).join("\n")}`.trim() : "";

  const writingSection = SITE.writing.filter(w => !w.title.startsWith("[")).length ? `
— Writing —
${SITE.writing.filter(w => !w.title.startsWith("[")).map(w => `${w.title} (${w.date}, ${w.kind}): ${w.blurb}\n  ${w.body[0]}`).join("\n")}`.trim() : "";

  return [base, basicInfoSection, workSection, educationSection, skillsSection, awardsSection, storiesSection, projectsSection, writingSection]
    .filter(Boolean)
    .join("\n\n");
}

function useChat() {
  const [messages, setMessages] = useState([]); // [{role, content}]
  const [pending, setPending] = useState(false);
  const [error, setError] = useState(null);

  const send = useCallback(async (text) => {
    const trimmed = text.trim();
    if (!trimmed || pending) return;
    setError(null);
    const next = [...messages, { role: "user", content: trimmed }];
    setMessages(next);
    setPending(true);

    try {
      const system = getSystemPrompt();
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          system,
          messages: next.map((m) => ({ role: m.role, content: m.content })),
        }),
      });
      if (response.status === 429) {
        let msg = "Too many messages — give it a minute.";
        try {
          const err = await response.json();
          if (err.error === "Chat is resting for today") msg = "The chat has hit its daily limit — come back tomorrow.";
        } catch {}
        throw new Error(msg);
      }
      if (!response.ok) throw new Error(`Request failed: ${response.status}`);
      const data = await response.json();
      setMessages((m) => [...m, { role: "assistant", content: data.content || "[no response]" }]);
    } catch (e) {
      setError(e && e.message ? e.message : "Something went wrong.");
    } finally {
      setPending(false);
    }
  }, [messages, pending]);

  const reset = useCallback(() => {
    setMessages([]);
    setError(null);
  }, []);

  return { messages, pending, error, send, reset };
}

/* -------------------------------------------------------------------------- */
/* Recommendations carousel state (shared across variants)                    */
/* -------------------------------------------------------------------------- */

function useCarousel(length) {
  const [i, setI] = useState(0);
  const next = useCallback(() => setI((v) => (v + 1) % length), [length]);
  const prev = useCallback(() => setI((v) => (v - 1 + length) % length), [length]);
  return { i, next, prev, set: setI };
}

/* -------------------------------------------------------------------------- */
/* Tiny page-router (in-memory, per variant)                                  */
/* -------------------------------------------------------------------------- */

function useRouter(initial = "home") {
  const [route, setRoute] = useState({ page: initial, slug: null });
  const goto = useCallback((page, slug = null) => setRoute({ page, slug }), []);
  return { route, goto };
}

/* -------------------------------------------------------------------------- */
/* Contact dropdown — styled per-variant via props                            */
/* -------------------------------------------------------------------------- */

function ContactDropdown({
  label = "Contact",
  triggerStyle,
  menuStyle,
  itemStyle,
  wrapStyle,
  align = "right",
}) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const baseWrap = { position: "relative", display: "inline-block" };
  const baseMenu = {
    position: "absolute",
    top: "calc(100% + 10px)",
    [align]: 0,
    minWidth: 180,
    display: "flex",
    flexDirection: "column",
    zIndex: 20,
  };

  return (
    <span ref={ref} style={{ ...baseWrap, ...wrapStyle }}>
      <span
        style={triggerStyle}
        onClick={() => setOpen((v) => !v)}
        aria-expanded={open}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setOpen((v) => !v); } }}
      >
        {label}
      </span>
      {open && (
        <div style={{ ...baseMenu, ...menuStyle }} role="menu">
          <a
            style={itemStyle}
            href={SITE.contact.linkedin}
            target="_blank"
            rel="noopener noreferrer"
            role="menuitem"
            onClick={() => setOpen(false)}
          >LinkedIn ↗</a>
          <a
            style={itemStyle}
            href={`mailto:${SITE.contact.email}`}
            role="menuitem"
            onClick={() => setOpen(false)}
          >Email</a>
        </div>
      )}
    </span>
  );
}

/* -------------------------------------------------------------------------- */
/* Export to window for cross-script use                                      */
/* -------------------------------------------------------------------------- */

Object.assign(window, {
  SITE,
  PROSE_DATE,
  SHORT_DATE,
  useChat,
  useCarousel,
  useRouter,
  ContactDropdown,
});
