"use client";

import { useEffect, useMemo, useState } from "react";

type EventItem = {
  id: number;
  slug: string;
  name: string;
  headline: string;
  tagline: string;
  accent: string;
  theme: string;
  photoMode: "required" | "optional" | "disabled";
  submissionMethod: "google-form" | "fillout";
  status: "active" | "deactivated";
  createdAt: string;
  messageCount: number;
  hasModeratorPassword: boolean;
};

type QrCode = {
  addData(value: string): void;
  make(): void;
  getModuleCount(): number;
  isDark(row: number, column: number): boolean;
};

declare global {
  interface Window {
    qrcode?: (typeNumber: number, errorCorrectionLevel: string) => QrCode;
  }
}

export default function EventManager() {
  const [events, setEvents] = useState<EventItem[]>([]);
  const [authLoading, setAuthLoading] = useState(true);
  const [authenticated, setAuthenticated] = useState(false);
  const [organiserName, setOrganiserName] = useState("");
  const [loginForm, setLoginForm] = useState({ username: "", password: "" });
  const [loginError, setLoginError] = useState("");
  const [busy, setBusy] = useState(false);
  const [notice, setNotice] = useState("");
  const [tab, setTab] = useState<"active" | "deactivated">("active");
  const [search, setSearch] = useState("");
  const [editing, setEditing] = useState<EventItem | null>(null);
  const [statusChange, setStatusChange] = useState<EventItem | null>(null);
  const [statusPassword, setStatusPassword] = useState("");
  const [statusError, setStatusError] = useState("");
  const [editForm, setEditForm] = useState({
    name: "", headline: "", tagline: "", theme: "garden", accent: "#f15a3b", password: "",
  });

  async function loadEvents() {
    await fetch("/api/events")
      .then((response) => (response.ok ? response.json() : Promise.reject()))
      .then((data) => setEvents(data.events || []))
      .catch(() => undefined);
  }

  useEffect(() => {
    fetch("/api/organiser-auth")
      .then((response) => response.json())
      .then(async (data) => {
        setAuthenticated(Boolean(data.authenticated));
        setOrganiserName(data.username || "");
        if (data.authenticated) await loadEvents();
      })
      .catch(() => setAuthenticated(false))
      .finally(() => setAuthLoading(false));
  }, []);

  async function login(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setBusy(true);
    setLoginError("");
    const response = await fetch("/api/organiser-auth", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(loginForm),
    });
    const data = await response.json();
    if (response.ok) {
      setAuthenticated(true);
      setOrganiserName(data.username || loginForm.username);
      setLoginForm({ username: "", password: "" });
      await loadEvents();
    } else {
      setLoginError(data.error || "Login failed.");
    }
    setBusy(false);
  }

  async function logout() {
    await fetch("/api/organiser-auth", { method: "DELETE" });
    setAuthenticated(false);
    setOrganiserName("");
    setEvents([]);
  }

  const counts = useMemo(() => ({
    active: events.filter((event) => event.status === "active").length,
    deactivated: events.filter((event) => event.status === "deactivated").length,
  }), [events]);

  const visibleEvents = useMemo(() => {
    const query = search.trim().toLowerCase();
    return events.filter((event) => {
      if (event.status !== tab) return false;
      if (!query) return true;
      return [event.name, event.headline, event.tagline, event.slug]
        .some((value) => value.toLowerCase().includes(query));
    });
  }, [events, search, tab]);

  function storedPassword(item: EventItem) {
    return window.sessionStorage.getItem(`flowmoments-moderator-${item.slug}`) || "";
  }

  function openEditor(item: EventItem) {
    setEditing(item);
    setEditForm({
      name: item.name,
      headline: item.headline,
      tagline: item.tagline,
      theme: item.theme,
      accent: item.accent,
      password: storedPassword(item),
    });
  }

  async function saveEventDetails(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!editing) return;
    setBusy(true);
    setNotice("");
    const response = await fetch(`/api/events/${editing.slug}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
        ...(editForm.password ? { "x-moderator-password": editForm.password } : {}),
      },
      body: JSON.stringify({
        mode: "details",
        name: editForm.name,
        headline: editForm.headline,
        tagline: editForm.tagline,
        theme: editForm.theme,
        accent: editForm.accent,
      }),
    });
    const data = await response.json();
    if (response.ok) {
      if (editForm.password) {
        window.sessionStorage.setItem(`flowmoments-moderator-${editing.slug}`, editForm.password);
      }
      setEvents((current) => current.map((item) =>
        item.slug === editing.slug ? data.event : item
      ));
      setNotice(data.ledgerSynced
        ? `“${data.event.name}” was updated in FlowMoments and the event ledger.`
        : `“${data.event.name}” was updated, but the ledger could not be reached.`);
      setEditing(null);
    } else {
      setNotice(data.error || "We couldn’t update the event.");
    }
    setBusy(false);
  }

  async function duplicateEvent(item: EventItem) {
    setBusy(true);
    const response = await fetch(`/api/events/${item.slug}/duplicate`, {
      method: "POST",
    });
    const data = await response.json();
    if (response.ok) {
      setEvents((current) => [data.event, ...current]);
      setNotice(data.ledgerSynced
        ? `Duplicated “${item.name}” and recorded it in the event ledger.`
        : `Duplicated “${item.name}”, but the Google Form ledger could not be reached.`);
    } else {
      setNotice(data.error || "We couldn’t duplicate the event.");
    }
    setBusy(false);
  }

  function requestEventStatus(item: EventItem) {
    const password = storedPassword(item);
    if (item.hasModeratorPassword && !password) {
      setStatusChange(item);
      setStatusPassword("");
      setStatusError("");
      return;
    }
    setEventStatus(item, password);
  }

  async function setEventStatus(item: EventItem, password: string) {
    const status = item.status === "active" ? "deactivated" : "active";
    setBusy(true);
    setStatusError("");
    const response = await fetch(`/api/events/${item.slug}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
        ...(password ? { "x-moderator-password": password } : {}),
      },
      body: JSON.stringify({ status }),
    });
    const data = await response.json();
    if (response.ok) {
      if (password) {
        window.sessionStorage.setItem(`flowmoments-moderator-${item.slug}`, password);
      }
      setEvents((current) => current.map((event) =>
        event.slug === item.slug ? data.event : event
      ));
      const action = status === "deactivated" ? "deactivated" : "reactivated";
      setNotice(data.ledgerSynced
        ? `“${item.name}” was ${action} and the change was added to the ledger.`
        : `“${item.name}” was ${action}, but the Google Form ledger could not be reached.`);
      setStatusChange(null);
      setStatusPassword("");
    } else {
      if (response.status === 401) {
        setStatusError(data.error || "Incorrect moderator password.");
      } else {
        setNotice(data.error || "We couldn’t update the event.");
      }
    }
    setBusy(false);
  }

  async function confirmEventStatus(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!statusChange) return;
    await setEventStatus(statusChange, statusPassword);
  }

  async function copyEventLink(item: EventItem, destination: "contribute" | "wall") {
    const url = `${window.location.origin}/e/${item.slug}/${destination}`;
    try {
      await navigator.clipboard.writeText(url);
      setNotice(`${destination === "contribute" ? "Guest" : "Wall"} link copied for “${item.name}”.`);
    } catch {
      setNotice(`Copy this link: ${url}`);
    }
  }

  async function shareWallUrl(item: EventItem) {
    const url = `${window.location.origin}/e/${item.slug}/wall`;
    if (navigator.share) {
      try {
        await navigator.share({
          title: `${item.name} live photo wall`,
          text: `Open the live photo wall for ${item.name}.`,
          url,
        });
        return;
      } catch (error) {
        if (error instanceof DOMException && error.name === "AbortError") return;
      }
    }
    try {
      await navigator.clipboard.writeText(url);
      setNotice(`Wall URL copied for “${item.name}”.`);
    } catch {
      setNotice(`Share this wall URL: ${url}`);
    }
  }

  async function shareModeratorUrl(item: EventItem) {
    const url = `${window.location.origin}/e/${item.slug}/manage`;
    if (navigator.share) {
      try {
        await navigator.share({
          title: `${item.name} moderator station`,
          text: `Manage and approve submissions for ${item.name}. The event moderator password is required.`,
          url,
        });
        return;
      } catch (error) {
        if (error instanceof DOMException && error.name === "AbortError") return;
      }
    }
    try {
      await navigator.clipboard.writeText(url);
      setNotice(`Moderator URL copied for “${item.name}”. Share the password separately.`);
    } catch {
      setNotice(`Share this moderator URL: ${url}. Send the password separately.`);
    }
  }

  async function loadQrCodeLibrary() {
    if (window.qrcode) return;
    await new Promise<void>((resolve, reject) => {
      const existing = document.querySelector<HTMLScriptElement>('script[data-flowmoments-qr]');
      if (existing) {
        existing.addEventListener("load", () => resolve(), { once: true });
        existing.addEventListener("error", () => reject(new Error("QR library failed")), { once: true });
        return;
      }
      const script = document.createElement("script");
      script.src = "/vendor/qrcode-generator.min.js";
      script.dataset.flowmomentsQr = "true";
      script.addEventListener("load", () => resolve(), { once: true });
      script.addEventListener("error", () => reject(new Error("QR library failed")), { once: true });
      document.head.appendChild(script);
    });
  }

  async function downloadContributionQr(item: EventItem) {
    try {
      await loadQrCodeLibrary();
      if (!window.qrcode) throw new Error("QR library unavailable");
      const url = `${window.location.origin}/e/${item.slug}/contribute`;
      const qr = window.qrcode(0, "M");
      qr.addData(url);
      qr.make();
      const canvas = document.createElement("canvas");
      canvas.width = 1024;
      canvas.height = 1024;
      const context = canvas.getContext("2d");
      if (!context) throw new Error("Canvas unavailable");
      const modules = qr.getModuleCount();
      const quietZone = 4;
      const total = modules + quietZone * 2;
      const cell = Math.floor(canvas.width / total);
      const drawingSize = cell * total;
      const offset = Math.floor((canvas.width - drawingSize) / 2);
      context.fillStyle = "#ffffff";
      context.fillRect(0, 0, canvas.width, canvas.height);
      context.fillStyle = "#1b2020";
      for (let row = 0; row < modules; row += 1) {
        for (let column = 0; column < modules; column += 1) {
          if (qr.isDark(row, column)) {
            context.fillRect(
              offset + (column + quietZone) * cell,
              offset + (row + quietZone) * cell,
              cell,
              cell
            );
          }
        }
      }
      const link = document.createElement("a");
      link.download = `${item.slug}-contribution-qr.png`;
      link.href = canvas.toDataURL("image/png");
      link.click();
      setNotice(`Contribution QR downloaded for “${item.name}”.`);
    } catch {
      setNotice("The contribution QR could not be created. Please try again.");
    }
  }

  if (authLoading) {
    return (
      <main className="organiser-login-page">
        <div className="organiser-login-card loading">
          <span className="brand-mark" aria-hidden="true"><span>F</span><i /></span>
          <p>Checking organiser access…</p>
        </div>
      </main>
    );
  }

  if (!authenticated) {
    return (
      <main className="organiser-login-page">
        <section className="organiser-login-card">
          <a className="brand organiser-login-brand" href="/">
            <span className="brand-mark" aria-hidden="true"><span>F</span><i /></span>
            <span>FlowMoments</span>
          </a>
          <span className="eyebrow coral">ORGANISER ACCESS</span>
          <h1>Welcome back.</h1>
          <p>Sign in to open the Event Library and manage your live walls.</p>
          <form onSubmit={login}>
            <label>
              <span>Username</span>
              <input
                required
                autoComplete="username"
                value={loginForm.username}
                onChange={(event) => setLoginForm({ ...loginForm, username: event.target.value })}
              />
            </label>
            <label>
              <span>Password</span>
              <input
                required
                type="password"
                autoComplete="current-password"
                value={loginForm.password}
                onChange={(event) => setLoginForm({ ...loginForm, password: event.target.value })}
              />
            </label>
            {loginError && <p className="login-error" role="alert">{loginError}</p>}
            <button className="primary-button" disabled={busy} type="submit">
              {busy ? "Signing in…" : "Open Event Library"}
            </button>
          </form>
          <a className="organiser-login-home" href="/">← Return to FlowMoments</a>
        </section>
      </main>
    );
  }

  return (
    <main className="manager-shell">
      <header className="manager-nav">
        <div className="brand-lockup">
          <a className="brand" href="/organiser">
            <span className="brand-mark" aria-hidden="true"><span>F</span><i /></span>
            <span>FlowMoments</span>
          </a>
          <a className="by-flowlab" href="https://www.flowlab.works" target="_blank" rel="noreferrer">by flowlab</a>
        </div>
        <div className="manager-account">
          <span>Signed in as <strong>{organiserName}</strong></span>
          <button type="button" onClick={logout}>Log out</button>
          <a className="primary-button compact" href="/event-creation.html">
            <span aria-hidden="true">＋</span> New event
          </a>
        </div>
      </header>

      <section className="manager-hero">
        <div>
          <span className="eyebrow coral">YOUR EVENTS</span>
          <h1>One wall.<br />A new story every time.</h1>
          <p>
            Create a private contribution page for guests and a separate,
            full-screen photo wall for the venue.
          </p>
        </div>
        <div className="split-preview" aria-label="Two separate experiences">
          <div className="phone-preview">
            <div className="phone-dot" />
            <span className="mini-label">GUEST LINK</span>
            <div className="mini-photo" />
            <div className="mini-line wide" />
            <div className="mini-line" />
            <div className="mini-button">Share moment</div>
          </div>
          <div className="wall-preview">
            <span className="mini-label light">VENUE SCREEN</span>
            <div className="preview-grid">
              {Array.from({ length: 6 }).map((_, index) => (
                <span key={index} className={`preview-tile tile-${index + 1}`} />
              ))}
            </div>
            <strong>Thank you for being part of our story.</strong>
          </div>
        </div>
      </section>

      <section className="event-section">
        <div className="section-heading">
          <div>
            <h2>Event library</h2>
            <p>Open, share or duplicate any event.</p>
          </div>
          <span className="event-count">{counts[tab]} {counts[tab] === 1 ? "event" : "events"}</span>
        </div>

        {notice && <p className="notice" role="status">{notice}</p>}

        <div className="event-library-tools">
          <div className="event-library-tabs" role="tablist" aria-label="Event status">
            <button className={tab === "active" ? "active" : ""} onClick={() => setTab("active")}>
              Active <b>{counts.active}</b>
            </button>
            <button className={tab === "deactivated" ? "active" : ""} onClick={() => setTab("deactivated")}>
              Deactivated <b>{counts.deactivated}</b>
            </button>
          </div>
          <label className="event-search">
            <span aria-hidden="true">⌕</span>
            <input
              type="search"
              value={search}
              onChange={(event) => setSearch(event.target.value)}
              placeholder="Search name, title or event code"
              aria-label="Search events"
            />
          </label>
        </div>

        <div className="event-grid">
          {visibleEvents.map((item) => (
            <article
              className={`event-card ${item.status === "deactivated" ? "deactivated" : ""}`}
              key={item.slug}
              style={{ "--event-accent": item.accent } as React.CSSProperties}
            >
              <div className={`event-art theme-${item.theme}`} style={{ "--event-accent": item.accent } as React.CSSProperties}>
                <div className="art-orb orb-one" />
                <div className="art-orb orb-two" />
                <div className="art-copy">
                  <span>WELCOME TO</span>
                  <strong>{item.headline}</strong>
                  <small>{item.tagline}</small>
                </div>
              </div>
              <div className="event-details">
                <div className="event-title-row">
                  <div>
                    <div className="event-name-line">
                      <h3>{item.name}</h3>
                      <span className={`event-status ${item.status}`}>{item.status}</span>
                    </div>
                    <p>
                      {item.messageCount} shared moments · {item.submissionMethod === "google-form" ? "Custom Google Form" : "Fillout embed"} · {item.photoMode === "required" ? "Photo required" : item.photoMode === "disabled" ? "Messages only" : "Photo optional"}
                    </p>
                  </div>
                  <button
                    className="icon-button"
                    aria-label={`Duplicate ${item.name}`}
                    disabled={busy}
                    onClick={() => duplicateEvent(item)}
                    title="Duplicate event"
                  >
                    ⧉
                  </button>
                </div>
                <div className="event-code-row">
                  <span>Event code</span>
                  <code>{item.slug}</code>
                </div>
                <div className="link-pair">
                  <a className="route-button manage" href={`/e/${item.slug}/manage`}>
                    <span className="route-icon">✓</span>
                    <span><small>ORGANISERS USE</small>Manage submissions</span>
                    <b>→</b>
                  </a>
                  <a className="route-button contribute" href={`/e/${item.slug}/contribute`}>
                    <span className="route-icon">↗</span>
                    <span><small>GUESTS USE</small>Contribution page</span>
                    <b>→</b>
                  </a>
                  <a className="route-button display" href={`/e/${item.slug}/wall`}>
                    <span className="route-icon">▣</span>
                    <span><small>DISPLAY ON</small>Live photo wall</span>
                    <b>→</b>
                  </a>
                </div>
                <div className="copy-link-row">
                  <button disabled={item.status === "deactivated"} onClick={() => copyEventLink(item, "contribute")}>Copy guest link</button>
                  <button disabled={item.status === "deactivated"} onClick={() => downloadContributionQr(item)}>Download guest QR</button>
                  <button disabled={item.status === "deactivated"} onClick={() => shareWallUrl(item)}>Share wall URL</button>
                  <button disabled={item.status === "deactivated"} onClick={() => shareModeratorUrl(item)}>Share moderator URL</button>
                  <button className="edit-event" onClick={() => openEditor(item)}>Edit event</button>
                  <button
                    className={item.status === "active" ? "deactivate-event" : "activate-event"}
                    disabled={busy}
                    onClick={() => requestEventStatus(item)}
                  >
                    {item.status === "active" ? "Deactivate event" : "Reactivate event"}
                  </button>
                </div>
              </div>
            </article>
          ))}
          {visibleEvents.length === 0 && (
            <div className="event-library-empty">
              <span>⌕</span>
              <strong>No {tab} events found</strong>
              <small>{search ? "Try a different search." : `Events will appear here when they are ${tab}.`}</small>
            </div>
          )}
          {tab === "active" && !search && <a className="new-event-card" href="/event-creation.html">
            <span>＋</span>
            <strong>Create another event</strong>
            <small>Open the complete event designer</small>
          </a>}
        </div>
      </section>

      <section className="how-it-works">
        <span className="eyebrow">A SIMPLE FLOW</span>
        <h2>Built for the room and the people in it.</h2>
        <div className="steps">
          <article><b>01</b><h3>Create</h3><p>Name your event and choose its colour.</p></article>
          <article><b>02</b><h3>Review</h3><p>Approve guest submissions before they reach the wall.</p></article>
          <article><b>03</b><h3>Display</h3><p>Open the live wall full-screen on the venue display.</p></article>
        </div>
      </section>

      {editing && (
        <div className="event-edit-overlay" role="presentation" onMouseDown={(event) => {
          if (event.target === event.currentTarget) setEditing(null);
        }}>
          <form className="event-edit-modal" onSubmit={saveEventDetails}>
            <header>
              <div><span className="eyebrow coral">EDIT EVENT</span><h2>Update event details</h2></div>
              <button type="button" onClick={() => setEditing(null)} aria-label="Close">×</button>
            </header>
            <p>Saving adds a new entry to the ledger, so the latest details become authoritative.</p>
            <div className="event-edit-fields">
              <label className="full"><span>Internal event name</span><input required maxLength={60} value={editForm.name} onChange={(event) => setEditForm({ ...editForm, name: event.target.value })} /></label>
              <label className="full"><span>Wall title</span><input required maxLength={70} value={editForm.headline} onChange={(event) => setEditForm({ ...editForm, headline: event.target.value })} /></label>
              <label className="full"><span>Short tagline</span><textarea maxLength={100} value={editForm.tagline} onChange={(event) => setEditForm({ ...editForm, tagline: event.target.value })} /></label>
              <label><span>Visual theme</span><select value={editForm.theme} onChange={(event) => setEditForm({ ...editForm, theme: event.target.value })}><option value="garden">Garden</option><option value="national-day">National Day</option><option value="wedding">Wedding</option><option value="halloween">Halloween</option><option value="celebration">Celebration</option></select></label>
              <label><span>Accent colour</span><input type="color" value={editForm.accent} onChange={(event) => setEditForm({ ...editForm, accent: event.target.value })} /></label>
              {editing.hasModeratorPassword && <label className="full"><span>Moderator password</span><input required type="password" autoComplete="current-password" value={editForm.password} onChange={(event) => setEditForm({ ...editForm, password: event.target.value })} /><small>Required to confirm your edit rights.</small></label>}
            </div>
            <footer><button type="button" onClick={() => setEditing(null)}>Cancel</button><button className="primary-button" disabled={busy} type="submit">{busy ? "Saving…" : "Save and update ledger"}</button></footer>
          </form>
        </div>
      )}
      {statusChange && (
        <div className="event-edit-overlay" role="presentation" onMouseDown={(event) => {
          if (event.target === event.currentTarget) setStatusChange(null);
        }}>
          <form className="event-edit-modal status-confirm-modal" onSubmit={confirmEventStatus}>
            <header>
              <div>
                <span className="eyebrow coral">CONFIRM CHANGE</span>
                <h2>{statusChange.status === "active" ? "Deactivate event?" : "Reactivate event?"}</h2>
              </div>
              <button type="button" onClick={() => setStatusChange(null)} aria-label="Close">×</button>
            </header>
            <p>
              Enter the moderator password for <strong>{statusChange.name}</strong>.
              This status change will also be recorded in the event ledger.
            </p>
            <div className="event-edit-fields">
              <label className="full">
                <span>Moderator password</span>
                <input
                  required
                  type="password"
                  autoComplete="current-password"
                  autoFocus
                  value={statusPassword}
                  onChange={(event) => setStatusPassword(event.target.value)}
                />
                {statusError && <small className="form-error" role="alert">{statusError}</small>}
              </label>
            </div>
            <footer>
              <button type="button" onClick={() => setStatusChange(null)}>Cancel</button>
              <button className="primary-button" disabled={busy} type="submit">
                {busy
                  ? "Saving…"
                  : statusChange.status === "active" ? "Deactivate event" : "Reactivate event"}
              </button>
            </footer>
          </form>
        </div>
      )}
    </main>
  );
}
