import { createFileRoute, notFound } from "@tanstack/react-router";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import type { CSSProperties } from "react";
import { useEffect, useRef } from "react";

import { FinalCtaBand } from "~/components/site/cta-band";
import { DestPlanCta, OpenTripLink, WhatsAppCta } from "~/components/site/ctas";
import { NotFound } from "~/components/site/not-found";
import { WindowFrame } from "~/components/site/window-frame";
import { STORY } from "~/lib/content";
import { ACCENT_HEX, getDestination } from "~/lib/destinations";
import { currentOrigin } from "~/lib/origin";

export const Route = createFileRoute("/$slug")({
  loader: async ({ params }) => {
    const dest = getDestination(params.slug);
    if (!dest) {
      throw notFound();
    }
    return { origin: await currentOrigin(), slug: dest.slug };
  },
  head: ({ loaderData }) => {
    const dest = loaderData ? getDestination(loaderData.slug) : undefined;
    if (!dest) {
      return {};
    }
    const origin = loaderData?.origin ?? "";
    const title = `${dest.name} Custom Trips from Karachi | Zaviamo`;
    const url = `${origin}/${dest.slug}`;
    const ogImage = `${origin}/assets/og/og-${dest.slug}.jpg`;
    return {
      meta: [
        { title },
        { name: "description", content: dest.blurb },
        { property: "og:title", content: title },
        { property: "og:description", content: dest.blurb },
        { property: "og:url", content: url },
        { property: "og:image", content: ogImage },
        { name: "twitter:title", content: title },
        { name: "twitter:description", content: dest.blurb },
        { name: "twitter:image", content: ogImage },
      ],
      links: [{ rel: "canonical", href: url }],
    };
  },
  notFoundComponent: NotFound,
  component: DestinationPage,
});

function DestinationPage() {
  const { slug } = Route.useParams();
  const dest = getDestination(slug);
  const frameRef = useRef<HTMLDivElement>(null);
  const driftRef = useRef<HTMLImageElement>(null);

  /* Slow parallax drift of the hero still behind the glass. */
  useEffect(() => {
    const frame = frameRef.current;
    const drift = driftRef.current;
    if (!frame || !drift) {
      return;
    }
    gsap.registerPlugin(ScrollTrigger);
    const mm = gsap.matchMedia();
    mm.add("(prefers-reduced-motion: no-preference)", () => {
      gsap.fromTo(
        drift,
        { yPercent: -5 },
        {
          yPercent: 5,
          ease: "none",
          scrollTrigger: {
            trigger: frame,
            start: "top bottom",
            end: "bottom top",
            scrub: 0.8,
          },
        }
      );
    });
    return () => {
      mm.revert();
    };
  }, []);

  if (!dest) {
    return <NotFound />;
  }

  const accent = ACCENT_HEX[dest.accent];
  const accentDeep = `color-mix(in srgb, ${accent} 52%, var(--ink))`;

  return (
    <main className="bg-cream text-ink">
      {/* Hero band on ink: a one-to-one replica of the stage chapter the
          visitor clicked, so the window simply expands into its page. */}
      <section className="zv-dest-hero text-cream">
        <div aria-hidden="true" className="zv-ws-vignette" />
        <div className="zv-dest-hero-copy">
          <h1 className="zv-script zv-ws-name">{dest.name}</h1>
          <p className="zv-ws-tagline">{dest.tagline}</p>
          <ul
            className="zv-ws-cities"
            style={{ "--accent": accent } as CSSProperties}
          >
            {dest.cities.map((city) => (
              <li className="zv-ws-city" key={city}>
                {city}
              </li>
            ))}
          </ul>
          <p className="zv-ws-duration">{dest.duration}</p>
          <div className="zv-dest-ctas">
            <DestPlanCta label={dest.ctaLabel} slug={dest.slug} />
            <WhatsAppCta />
          </div>
        </div>

        <div className="zv-dest-hero-window" ref={frameRef}>
          <WindowFrame>
            <img
              alt={dest.name}
              className="h-full w-full scale-110 object-cover"
              ref={driftRef}
              src={dest.image}
            />
          </WindowFrame>
        </div>
      </section>

      {/* Editorial body */}
      <div className="mx-auto max-w-[46rem] px-6 py-[clamp(3rem,8vh,5rem)]">
        <p className="zv-dest-lede">{dest.blurb}</p>
        <h2 className="text-[clamp(1.6rem,2.8vw,2.3rem)] font-bold leading-tight tracking-tight">
          {dest.h2}
        </h2>
        {dest.body.map((paragraph) => (
          <p className="mt-6 leading-relaxed text-ink/85" key={paragraph}>
            {paragraph}
          </p>
        ))}
      </div>

      {/* Highlights */}
      <div className="mx-auto max-w-6xl px-6 pb-[clamp(5rem,12vh,8rem)] md:px-10">
        <p className="zv-eyebrow text-ink/50">On the ground</p>
        <div className="mt-8 grid gap-6 md:grid-cols-3">
          {dest.highlights.map((highlight) => (
            <article
              className="zv-highlight"
              key={highlight.title}
              style={{ background: `${accent}1c` }}
            >
              <h3
                className="text-lg font-bold"
                style={{ color: accentDeep } as CSSProperties}
              >
                {highlight.title}
              </h3>
              <p className="mt-2.5 text-[0.95rem] leading-relaxed text-ink/80">
                {highlight.text}
              </p>
            </article>
          ))}
        </div>
      </div>

      {/* Ink quote band, then back to every window */}
      <section className="bg-ink py-[clamp(4.5rem,11vh,7.5rem)] text-cream">
        <div className="mx-auto max-w-3xl px-6">
          <p className="zv-pullquote text-cream">{STORY.pullQuote}</p>
          <div className="mt-10">
            <OpenTripLink
              accent={accent}
              label="See every window"
              toWindows
            />
          </div>
        </div>
      </section>

      {/* Final CTA band on ink */}
      <section className="bg-ink pb-[clamp(3rem,8vh,5rem)] pt-4">
        <div className="mx-auto max-w-6xl px-5 md:px-8">
          <FinalCtaBand primary={<DestPlanCta label={dest.ctaLabel} slug={dest.slug} />} />
        </div>
      </section>
    </main>
  );
}
