import { notFound } from "next/navigation";
import type { Metadata } from "next";
import { and, asc, eq, gte, inArray, sql } from "drizzle-orm";
import { db } from "@db/client";
import { events, ticketTypes } from "@db/schema";
import SiteNav from "@/components/site-nav";
import SiteFooter from "@/components/site-footer";
import { getShopBySlug, listProducts } from "@db/queries/merch";
import { eventPath } from "@/lib/event-url";
import { formatEventWhen, nowMs } from "@/lib/format";
import { toPublicProducts } from "@/lib/merch-public";
import ShopClient, { type StoreEvent } from "./shop-client";

export const dynamic = "force-dynamic";

export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
  const shop = await getShopBySlug((await params).slug);
  if (!shop || !shop.open) return {};
  return {
    title: `${shop.name} · VibePass`,
    description: shop.description?.slice(0, 150) ?? `Tickets and official merchandise from ${shop.name}.`,
    openGraph: shop.bannerUrl ? { images: [{ url: shop.bannerUrl }] } : undefined,
  };
}

// The organizer's storefront: their upcoming events AND their merch on one
// page (All / Events / Merch), like a HustleSasa store.
export default async function ShopPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const shop = await getShopBySlug(slug);
  if (!shop || !shop.open) notFound();

  const products = await listProducts(shop.id, { publicOnly: true });

  // Upcoming published events by the same organizer.
  const now = new Date(nowMs());
  const evRows = await db
    .select({
      id: events.id,
      title: events.title,
      slug: events.slug,
      startsAt: events.startsAt,
      endsAt: events.endsAt,
      venue: events.venue,
      city: events.city,
      coverImageUrl: events.coverImageUrl,
    })
    .from(events)
    .where(
      and(
        eq(events.organizerId, shop.organizerId),
        eq(events.status, "published"),
        gte(sql`coalesce(${events.endsAt}, ${events.startsAt})`, now)
      )
    )
    .orderBy(asc(events.startsAt))
    .limit(24);
  const prices = evRows.length
    ? await db
        .select({ eventId: ticketTypes.eventId, min: sql<number>`min(${ticketTypes.priceCents})` })
        .from(ticketTypes)
        .where(inArray(ticketTypes.eventId, evRows.map((e) => e.id)))
        .groupBy(ticketTypes.eventId)
    : [];
  const minByEvent = new Map(prices.map((p) => [p.eventId, Number(p.min)]));
  const storeEvents: StoreEvent[] = evRows.map((e) => ({
    id: e.id,
    title: e.title,
    href: eventPath(e),
    when: formatEventWhen(e.startsAt.toISOString(), e.endsAt ? e.endsAt.toISOString() : null),
    where: [e.venue, e.city].filter(Boolean).join(", ") || null,
    coverImageUrl: e.coverImageUrl,
    fromCents: minByEvent.has(e.id) ? minByEvent.get(e.id)! : null,
  }));

  // Event badges for products that promote an event (any status).
  const eventIds = [...new Set(products.map((p) => p.eventId).filter((x): x is string => !!x))];
  const badgeRows = eventIds.length
    ? await db.select({ id: events.id, title: events.title, slug: events.slug }).from(events).where(inArray(events.id, eventIds))
    : [];
  const eventById = new Map(badgeRows.map((e) => [e.id, { id: e.id, title: e.title, href: eventPath(e) }]));

  return (
    <div className="flex-1 bg-bg text-ink">
      <SiteNav />
      <section className="relative overflow-hidden border-b border-line">
        {shop.bannerUrl && (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={shop.bannerUrl} alt="" className="absolute inset-0 h-full w-full object-cover opacity-30" />
        )}
        <div className="relative mx-auto max-w-6xl px-4 py-14">
          <p className="text-xs font-semibold uppercase tracking-[0.3em] text-brand-green-h">Official store</p>
          <h1 className="mt-2 text-3xl font-black sm:text-4xl">{shop.name}</h1>
          {shop.description && <p className="mt-3 max-w-2xl text-muted">{shop.description}</p>}
        </div>
      </section>

      <main className="mx-auto max-w-6xl px-4 py-10">
        <ShopClient
          shop={{
            id: shop.id,
            pickupEnabled: shop.pickupEnabled,
            deliveryEnabled: shop.deliveryEnabled,
            deliveryFeeCents: shop.deliveryFeeCents,
            pickupInstructions: shop.pickupInstructions,
          }}
          products={toPublicProducts(products, eventById)}
          events={storeEvents}
        />
      </main>
      <SiteFooter />
    </div>
  );
}
