import { cache } from "react";
import type { Metadata } from "next";
import Link from "next/link";
import { notFound, permanentRedirect } from "next/navigation";
import { eventIdFromParam, eventPath, eventPathSegment } from "@/lib/event-url";
import Marquee from "@/components/marquee";
import SiteNav from "@/components/site-nav";
import SiteFooter from "@/components/site-footer";
import { formatEventWhen, nowMs } from "@/lib/format";
import { getEventMerchSafe } from "@db/queries/merch";
import { toPublicProducts } from "@/lib/merch-public";
import { getEventGallery } from "@db/queries/gallery-db";
import { getEventById, getEventBySlugOrId, getEventLinks } from "@db/queries/events";
import TicketSelector, { type PublicTicketType } from "./ticket-selector";
import EventGallery from "./event-gallery";
import SubmitPhotos from "./submit-photos";
import EventLinks from "./event-links";

const MAX_PER_ORDER = 10;

// One DB read per request, shared by generateMetadata and the page. A param
// ending in a UUID (a bare id, or a "<name>-<uuid>" link) is looked up by id;
// anything else is the event's stored slug.
const UUID_AT_END = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const loadEvent = cache((param: string) => {
  const decoded = decodeURIComponent(param);
  return UUID_AT_END.test(decoded) ? getEventById(eventIdFromParam(decoded)) : getEventBySlugOrId(decoded);
});

// Link previews (WhatsApp, Facebook, X, iMessage...) read these tags, so a
// shared event link shows the event's name, date and cover instead of the
// generic site title.
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
  const event = await loadEvent((await params).id);
  if (!event) return {};

  const when = formatEventWhen(event.starts_at, event.ends_at);
  const where = [event.venue, event.city].filter(Boolean).join(", ");
  const blurb = event.description?.replace(/\s+/g, " ").trim().slice(0, 150);
  const description = [when, where].filter(Boolean).join(" · ") + (blurb ? ` — ${blurb}` : "");
  const title = `${event.title} · VibePass Tickets`;
  const images = event.cover_image_url ? [{ url: event.cover_image_url, alt: event.title }] : undefined;

  return {
    title,
    description,
    alternates: { canonical: eventPath(event) },
    openGraph: { type: "website", siteName: "VibePass Tickets", title: event.title, description, url: eventPath(event), images },
    twitter: { card: images ? "summary_large_image" : "summary", title: event.title, description, images: images?.map((i) => i.url) },
  };
}

export default async function EventDetailPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<Record<string, string | string[] | undefined>>;
}) {
  const { id } = await params;
  const query = await searchParams;

  const event = await loadEvent(id);
  if (!event) notFound();

  // Bare-id and "<name>-<uuid>" links land on the event's /events/<slug>
  // URL, so whatever gets copied from the address bar is the named link.
  if (decodeURIComponent(id) !== eventPathSegment(event)) {
    // Carry the query string over -- it holds ?ref=<affiliate code>.
    const query = new URLSearchParams();
    for (const [key, value] of Object.entries(await searchParams)) {
      for (const v of Array.isArray(value) ? value : value === undefined ? [] : [value]) query.append(key, v);
    }
    const qs = query.toString();
    permanentRedirect(eventPath(event) + (qs ? `?${qs}` : ""));
  }

  // Strip stock/sales counts before anything reaches the browser (see
  // PublicTicketType). POPULAR goes to the best-selling tier, or on a fresh
  // event the middle tier, so the badge still lands somewhere sensible.
  const rawTypes = event.ticket_types ?? [];
  const now = nowMs();
  const salesClosed = (tt: (typeof rawTypes)[number]) =>
    tt.sales_closed || (tt.sales_end_at !== null && new Date(tt.sales_end_at).getTime() <= now);
  const topSeller = [...rawTypes].sort((a, b) => b.quantity_sold - a.quantity_sold)[0];
  const popularId =
    topSeller && topSeller.quantity_sold > 0 ? topSeller.id : rawTypes[Math.floor(rawTypes.length / 2)]?.id;
  const ticketTypes: PublicTicketType[] = rawTypes.map((tt) => ({
    id: tt.id,
    name: tt.name,
    price_cents: tt.price_cents,
    original_price_cents: tt.original_price_cents,
    currency: tt.currency,
    admits_count: tt.admits_count,
    // Closed (by hand or past its stop-selling time) => nothing to pick.
    max_per_order: salesClosed(tt) ? 0 : Math.max(0, Math.min(tt.quantity_total - tt.quantity_sold, MAX_PER_ORDER)),
    closed: salesClosed(tt),
    popular: tt.id === popularId,
  }));

  // Past events swap the ticket panel for a photo gallery — "relive it".
  const isPast = new Date(event.ends_at ?? event.starts_at).getTime() < nowMs();
  const [photos, links] = isPast
    ? await Promise.all([getEventGallery(event.id), getEventLinks(event.id)])
    : [[], []];

  // Organizer's merch: shown on the page and sold in the ticket checkout.
  const eventMerch = await getEventMerchSafe(event.organizer_id, event.id);
  const shopSlug = eventMerch?.shop.slug ?? null;
  const merchForCheckout = eventMerch && !isPast
    ? {
        shop: {
          id: eventMerch.shop.id,
          slug: eventMerch.shop.slug,
          name: eventMerch.shop.name,
          pickupEnabled: eventMerch.shop.pickupEnabled,
          deliveryEnabled: eventMerch.shop.deliveryEnabled,
          deliveryFeeCents: eventMerch.shop.deliveryFeeCents,
          pickupInstructions: eventMerch.shop.pickupInstructions,
        },
        products: toPublicProducts(
          eventMerch.products,
          new Map([[event.id, { id: event.id, title: event.title, href: eventPath(event) }]])
        ),
      }
    : null;

  return (
    <div className="flex-1 bg-bg">
      {/* Hero */}
      <section className="relative overflow-hidden">
        {event.cover_image_url && (
          <>
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={event.cover_image_url}
              alt={event.title}
              className="absolute inset-0 w-full h-full object-cover opacity-40"
            />
            <div className="absolute inset-0 bg-gradient-to-t from-bg via-bg/85 to-bg/50" />
          </>
        )}
        <div className="relative">
          <SiteNav transparent />
          <div className="max-w-6xl mx-auto px-4 pt-12 pb-20">
            <div className="flex flex-wrap items-center gap-3">
              <p className="text-xs font-semibold uppercase tracking-[0.3em] text-brand-green-h">
                {event.categories?.name ?? "Tickets"} · {event.city ?? event.venue}
              </p>
              {event.age_restriction && (
                <span className="rounded-full bg-brand-orange px-2.5 py-0.5 text-[11px] font-bold text-white">
                  {event.age_restriction}
                </span>
              )}
            </div>
            <h1 className="mt-4 text-4xl sm:text-6xl font-black leading-[0.95] tracking-tight text-white">
              {event.title}
            </h1>
            {event.organizer_name && (
              <p className="mt-3 text-lg font-semibold text-brand-green-h">
                By {event.organizer_name}
              </p>
            )}
            <p className="mt-4 text-lg text-ink/80">
              {formatEventWhen(event.starts_at, event.ends_at)}
            </p>
            {event.venue && <p className="mt-1 text-sm text-muted">{event.venue}</p>}
            {isPast ? (
              <a
                href="#gallery"
                className="mt-8 inline-flex items-center gap-2 rounded-full bg-brand-green px-7 py-3 text-base font-semibold text-white hover:bg-brand-green-h"
              >
                {photos.length ? `View ${photos.length} photos` : "Past event"}
              </a>
            ) : (
              <a
                href="#tickets"
                className="mt-8 inline-block rounded-full bg-brand-green px-7 py-3 text-base font-semibold text-white hover:bg-brand-green-h"
              >
                Pick your pass
              </a>
            )}
            {shopSlug && (
              <Link
                href={`/shop/${shopSlug}`}
                className="mt-8 ml-3 inline-block rounded-full border border-white/30 px-7 py-3 text-base font-semibold text-white hover:bg-white/10"
              >
                Shop merch
              </Link>
            )}
          </div>
        </div>
      </section>

      <Marquee />

      <main className="bg-bg">
        <div className="max-w-6xl mx-auto px-4 py-16 grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)] gap-12">
          {/* About */}
          <div className="min-w-0">
            <h2 className="text-2xl font-black tracking-tight text-white">About this event</h2>
            {event.description && (
              <p className="mt-4 text-muted whitespace-pre-wrap leading-relaxed">
                {event.description}
              </p>
            )}
          </div>

          {isPast ? (
            /* Gallery — past events relive the moment instead of selling tickets */
            <div id="gallery" className="min-w-0 scroll-mt-8">
              <div className="flex items-baseline justify-between">
                <h2 className="text-2xl font-black tracking-tight text-white">Event gallery</h2>
                {photos.length > 0 && (
                  <span className="text-xs text-muted">{photos.length} photos</span>
                )}
              </div>
              <div className="mt-5 space-y-5">
                {links.length > 0 && <EventLinks links={links} />}
                {photos.length > 0 ? (
                  <EventGallery photos={photos} title={event.title} eventId={event.id} />
                ) : (
                  <div className="rounded-2xl border border-line bg-panel p-10 text-center">
                    <p className="font-semibold text-white">Photos coming soon.</p>
                    <p className="mt-2 text-sm text-muted">
                      Be the first to share shots from this event using the form below.
                    </p>
                  </div>
                )}
                <SubmitPhotos eventId={event.id} />
              </div>
            </div>
          ) : (
            /* Tickets */
            <div id="tickets" className="min-w-0 scroll-mt-8">
              <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1">
                <h2 className="text-2xl font-black tracking-tight text-white">Pick your pass</h2>
                <span className="text-xs text-muted">Prices in KES · M-Pesa STK push</span>
              </div>
              <div className="mt-5">
                <TicketSelector
                  eventId={event.id}
                  ticketTypes={ticketTypes}
                  paymentFailed={query.payment === "failed"}
                  merch={merchForCheckout}
                />
              </div>
            </div>
          )}
        </div>
      </main>

      <SiteFooter />
    </div>
  );
}
