import type { Metadata } from "next";
import Image from "next/image";
import { setRequestLocale } from "next-intl/server";
import { connectDB } from "@/lib/db";
import { Convention } from "@/models/Convention";
import { WaitlistEntry } from "@/models/WaitlistEntry";
import { getSessionClientId } from "@/lib/auth";
import { Link } from "@/i18n/navigation";
import { ScrollReveal } from "@/components/ScrollReveal";
import { PageHeaderBanner } from "@/components/PageHeaderBanner";
import { WaitlistForm } from "@/components/WaitlistForm";
import { buildPageMetadata } from "@/lib/seo";

export const dynamic = "force-dynamic";

// Feste 1120px-Content-Spalte + feste Breakpoints, wie in
// reference/subpage-header-spec festgelegt — kein vw/clamp.
const COL = "mx-auto w-full max-w-[1120px] px-5 sm:px-8";

export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
  const { locale } = await params;
  return buildPageMetadata({
    locale,
    path: "/conventions",
    title: "Conventions",
    description:
      locale === "en"
        ? "Upcoming conventions with Rakku Photography — request a slot or join the waitlist if it's already booked out."
        : "Anstehende Conventions mit Rakku Photography — Slot anfragen oder auf die Warteliste, falls schon ausgebucht.",
  });
}

export default async function ConventionsPage({ params }: { params: Promise<{ locale: string }> }) {
  const { locale } = await params;
  setRequestLocale(locale);
  const isEn = locale === "en";

  await connectDB();
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const [conventionDocs, clientId] = await Promise.all([
    Convention.find({ visible: true, endDate: { $gte: today } }).sort({ startDate: 1 }).lean(),
    getSessionClientId(),
  ]);

  const myEntries = clientId
    ? await WaitlistEntry.find({ clientId, conventionId: { $in: conventionDocs.map((c) => c._id) } })
        .select("conventionId")
        .lean()
    : [];
  const myEntryConventionIds = new Set(myEntries.map((e) => String(e.conventionId)));

  // Preview-only Beispiel-Convention, damit sich das Karten-Design auch bei
  // noch leerer conventions-Collection ansehen lässt. Die Variable ist NUR im
  // Preview-Worktree gesetzt (.env* ist gitignored) — auf der Live-Seite
  // bleibt es bei der echten (ggf. leeren) DB-Liste.
  const conventions =
    conventionDocs.length === 0 && process.env.PREVIEW_SAMPLE_DATA === "1"
      ? [
          {
            _id: "sample-dokomi-2027",
            name: "DoKomi 2027",
            location: "Messe Düsseldorf",
            startDate: new Date("2027-07-09T00:00:00Z"),
            endDate: new Date("2027-07-11T00:00:00Z"),
            infoUrl: "https://www.dokomi.de",
            slotsAvailable: true,
            image: "",
            logo: "",
            notes:
              "Deutschlands größte Japan- und Anime-Expo — ich bin mit Kamera vor Ort, Slots können vorab angefragt werden.",
            notesEn:
              "Germany's largest Japan & anime expo — I'll be there with my camera, slots can be requested in advance.",
          } as unknown as (typeof conventionDocs)[number],
        ]
      : conventionDocs;

  const localeTag = isEn ? "en-GB" : "de-DE";
  const fmtDate = (d: Date) =>
    new Date(d).toLocaleDateString(localeTag, { day: "2-digit", month: "long", year: "numeric" });

  // "9.–11. Juli 2027" wenn Start/Ende im selben Monat liegen, sonst der
  // volle Bereich; ein einzelner Tag bleibt ein einzelnes Datum.
  const fmtRange = (start: Date, end: Date) => {
    const s = new Date(start);
    const e = new Date(end);
    if (s.toDateString() === e.toDateString()) return fmtDate(s);
    if (s.getMonth() === e.getMonth() && s.getFullYear() === e.getFullYear()) {
      const monthYear = s.toLocaleDateString(localeTag, { month: "long", year: "numeric" });
      return isEn
        ? `${monthYear.split(" ")[0]} ${s.getDate()}–${e.getDate()}, ${s.getFullYear()}`
        : `${s.getDate()}.–${e.getDate()}. ${monthYear}`;
    }
    return `${fmtDate(s)} – ${fmtDate(e)}`;
  };

  type Conv = (typeof conventions)[number];

  // Einheitlicher Weg für beide Fälle: der Kunde trägt sich ein (WaitlistEntry),
  // KEIN selbst erstellter Auftrag. Rakku bestätigt im Admin mit festem Termin
  // (grantWaitlistEntryAction) — daraus entsteht der Auftrag. `slotsAvailable`
  // steuert nur die Beschriftung.
  const renderActions = (c: Conv) => {
    const alreadyOnList = myEntryConventionIds.has(String(c._id));

    if (alreadyOnList) {
      return (
        <p className="text-sm text-[var(--rk-ink-muted)]">
          {isEn ? "You're on the list — " : "Du bist eingetragen — "}
          <Link href="/account/conventions" className="underline hover:text-[var(--rk-ink)]">
            {isEn ? "view status" : "Status ansehen"}
          </Link>
        </p>
      );
    }

    if (!clientId) {
      return (
        <p className="text-sm text-[var(--rk-ink-muted)]">
          {isEn ? "Please " : "Bitte "}
          <Link href={`/login?next=%2F${locale}%2Fconventions`} className="underline hover:text-[var(--rk-ink)]">
            {isEn ? "log in" : "einloggen"}
          </Link>{" "}
          {isEn ? "or " : "oder "}
          <Link href={`/register?next=%2F${locale}%2Fconventions`} className="underline hover:text-[var(--rk-ink)]">
            {isEn ? "create an account" : "ein Konto erstellen"}
          </Link>{" "}
          {isEn
            ? "to request a slot — you'll then see the status in your account."
            : "um einen Slot anzufragen — den Status siehst du danach in deinem Konto."}
        </p>
      );
    }

    return (
      <WaitlistForm
        conventionId={String(c._id)}
        locale={locale}
        conventionStart={new Date(c.startDate).toISOString()}
        conventionEnd={new Date(c.endDate).toISOString()}
        triggerLabel={
          c.slotsAvailable
            ? isEn
              ? "Request a slot"
              : "Slot anfragen"
            : isEn
              ? "Join waitlist"
              : "Auf Warteliste eintragen"
        }
      />
    );
  };

  const [featured, ...rest] = conventions;

  return (
    // Opake --rk-bg-Fläche blockt den weißen Radial-Schimmer des body-Hintergrunds.
    // Header/Nav/Banner: geteilte Behandlung — siehe reference/subpage-header-spec.
    <main className="min-h-screen bg-[var(--rk-bg)] pb-24">
      <PageHeaderBanner
        image="/img/conventions-banner.jpg"
        eyebrow="Conventions"
        title={isEn ? "Where to find Rakku" : "Wo trefft ihr Rakku?"}
        subtitle={
          isEn
            ? "These are the conventions I'm heading to next — request a slot in advance, or join the waitlist if one is already booked out."
            : "Das sind die Conventions, auf denen ich als Nächstes bin — Slot vorab anfragen, oder auf die Warteliste, falls schon ausgebucht."
        }
        focalPoint="50% 32%"
        tall
      />

      {featured ? (
        <section className={`${COL} -mt-8 pt-14 sm:pt-20`}>
          {/* Nächste Convention — große Foto-Karte */}
          <ScrollReveal>
            <article className="relative overflow-hidden rounded-2xl border border-white/10 shadow-[0_24px_60px_-20px_rgba(0,0,0,0.55)]">
              <Image
                src={featured.image || "/img/conventions-featured.jpg"}
                alt=""
                fill
                sizes="1120px"
                className="object-cover"
                style={{ objectPosition: "50% 40%" }}
              />
              <div
                className="absolute inset-0"
                style={{
                  background:
                    "linear-gradient(100deg, rgba(16,16,18,0.94) 0%, rgba(16,16,18,0.84) 40%, rgba(16,16,18,0.4) 72%, rgba(16,16,18,0.12) 100%)",
                }}
              />
              <div className="rk-grain absolute inset-0" />
              {featured.logo && (
                <div className="pointer-events-none absolute right-4 top-4 z-10 flex max-w-[45%] justify-end sm:right-8 sm:top-8">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={featured.logo}
                    alt={featured.name}
                    className="h-14 w-auto max-w-full object-contain object-right [filter:drop-shadow(0_1px_2px_rgba(0,0,0,0.9))_drop-shadow(0_4px_16px_rgba(0,0,0,0.65))] sm:h-20"
                  />
                </div>
              )}
              <div className="relative max-w-xl p-8 sm:p-12">
                <p className="text-xs uppercase tracking-[0.3em] text-[var(--rk-accent)]">
                  {isEn ? "Next convention" : "Nächste Convention"}
                </p>
                <p className="rk-wordmark mt-3 text-3xl sm:text-4xl">
                  {fmtRange(featured.startDate, featured.endDate)}
                </p>
                <p className="rk-wordmark mt-2 text-lg text-[var(--rk-ink-muted)] sm:text-xl">{featured.name}</p>
                {featured.location && (
                  <p className="mt-3 text-sm text-[var(--rk-ink-muted)]">📍 {featured.location}</p>
                )}
                {((isEn && featured.notesEn) || featured.notes) && (
                  <p className="mt-4 max-w-md text-sm leading-relaxed text-[var(--rk-ink-muted)]">
                    {(isEn && featured.notesEn) || featured.notes}
                  </p>
                )}
                <div className="mt-7 flex flex-wrap items-center gap-x-6 gap-y-4">
                  {renderActions(featured)}
                  {featured.infoUrl && (
                    <a
                      href={featured.infoUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-xs uppercase tracking-[0.18em] text-[var(--rk-ink-muted)] underline underline-offset-4 hover:text-[var(--rk-ink)]"
                    >
                      {isEn ? "Convention website" : "Zur Convention-Seite"}
                    </a>
                  )}
                </div>
              </div>
            </article>
          </ScrollReveal>

          {/* Weitere Conventions — kompakte Karten */}
          {rest.length > 0 && (
            <div className="mt-6 flex flex-col gap-4">
              {rest.map((c, i) => (
                <ScrollReveal key={String(c._id)} delayMs={i * 80}>
                  <div className="rounded-xl border border-white/10 bg-[var(--rk-surface)] p-6">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div>
                        {c.logo && (
                          // eslint-disable-next-line @next/next/no-img-element
                          <img
                            src={c.logo}
                            alt=""
                            className="mb-2 h-7 w-auto max-w-[10rem] object-contain object-left opacity-90"
                          />
                        )}
                        <h3 className="rk-wordmark text-base">
                          <Link href={`/conventions/${c._id}`} className="transition-colors hover:text-[var(--rk-accent)]">
                            {c.name}
                          </Link>
                        </h3>
                        <p className="mt-1 text-sm text-[var(--rk-ink-muted)]">
                          {fmtRange(c.startDate, c.endDate)}
                          {c.location ? ` · ${c.location}` : ""}
                        </p>
                        {((isEn && c.notesEn) || c.notes) && (
                          <p className="mt-1 text-xs text-[var(--rk-ink-muted)]">{(isEn && c.notesEn) || c.notes}</p>
                        )}
                      </div>
                      {c.infoUrl && (
                        <a
                          href={c.infoUrl}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="shrink-0 text-xs text-[var(--rk-ink-muted)] underline hover:text-[var(--rk-ink)]"
                        >
                          {isEn ? "Convention website" : "Zur Convention-Seite"}
                        </a>
                      )}
                    </div>
                    <div className="mt-4">{renderActions(c)}</div>
                  </div>
                </ScrollReveal>
              ))}
            </div>
          )}

          {/* Weicher Abschluss statt harter Trennlinie (reference-spec: keine
              grauen border-Striche zwischen gleichfarbigen Abschnitten) */}
          <ScrollReveal className="mt-16 text-center">
            <div className="rk-accent-rule rk-accent-rule--center" />
            <h2 className="rk-wordmark mt-4 text-lg sm:text-xl">
              {isEn ? "Nothing else new" : "Sonst noch nichts Neues"}
            </h2>
            <p className="mx-auto mt-3 max-w-md text-sm leading-relaxed text-[var(--rk-ink-muted)]">
              {isEn
                ? "I'll add more dates here as soon as they're confirmed — check back soon or follow me on Instagram for updates."
                : "Weitere Termine trage ich ein, sobald sie feststehen — schau gerne bald wieder vorbei oder folge mir auf Instagram für Updates."}
            </p>
          </ScrollReveal>
        </section>
      ) : (
        <section className={`${COL} -mt-8 pt-20 text-center sm:pt-28`}>
          <ScrollReveal>
            <div className="rk-accent-rule rk-accent-rule--center" />
            <h2 className="rk-wordmark mt-4 text-xl sm:text-2xl">
              {isEn ? "Nothing planned right now" : "Aktuell nichts geplant"}
            </h2>
            <p className="mx-auto mt-3 max-w-md text-sm leading-relaxed text-[var(--rk-ink-muted)]">
              {isEn
                ? "No upcoming conventions listed right now — check back soon or follow me on Instagram for updates."
                : "Aktuell sind keine Conventions eingetragen — schau bald wieder vorbei oder folge mir auf Instagram für Updates."}
            </p>
          </ScrollReveal>
        </section>
      )}
    </main>
  );
}
