import type { Metadata } from "next";
import { cache } from "react";
import Link from "next/link";
import { Header } from "@/components/header/Header";
import { Footer } from "@/components/footer/Footer";
import { defineQuery } from "next-sanity";
import { sanity } from "@/lib/sanity";
import { ReleaseCover } from "@/components/release/ReleaseCover";
import { urlFor } from "@/lib/sanityImage";
import { ARTIST_PLACEHOLDER_SRC, CARD_GRID_CLASSES_4 } from "@/lib/constants";
import { ArrowLink } from "@/components/ArrowLink";
import { IconButtonLink } from "@/components/IconButton";
import { IoPersonOutline } from "react-icons/io5";
import { ReleaseCard, type ReleaseCardData } from "@/components/release/ReleaseCard";
import { BlogCard, type BlogCardData } from "@/components/blog/BlogCard";
import { ConcertTable, type ConcertData } from "@/components/concert/ConcertTable";
import { formatYears } from "@/components/artist/types";
import type { SanityImageSource } from "@sanity/image-url";
import type { TrackData } from "@/components/release/Tracklist";
import { FeaturedReleaseActions } from "@/components/release/FeaturedReleaseActions";

export const revalidate = 86400;

type FeaturedAlbum = {
  name?: string;
  albumArtist?: string;
  slug?: string;
  albumCover?: SanityImageSource;
  shortDescription?: string;
  tracks?: TrackData[];
};

type FeaturedArtist = {
  name?: string;
  role?: string;
  slug?: string;
  image?: SanityImageSource;
  bioExcerpt?: string;
};

type FeaturedComposer = {
  name?: string;
  slug?: string;
  birthYear?: number;
  deathYear?: number;
  image?: SanityImageSource;
  bioExcerpt?: string;
};

type HomeSettings = {
  featuredAlbum: FeaturedAlbum | null;
  featuredArtist: FeaturedArtist | null;
  featuredComposer: FeaturedComposer | null;
};

const SETTINGS_QUERY = defineQuery(`
*[_type == "settings"][0]{
  "featuredAlbum": featuredAlbum->{
    name,
    albumArtist,
    "slug": slug.current,
    albumCover,
    shortDescription,
    "tracks": tracks[]{
      "workId": work->_id,
      "workTitle": work->title,
      "composerName": work->composer->name,
      "arrangerName": work->arranger->name,
      movement,
      displayTitle,
      duration,
      artist,
      "previewMp3Url": previewMp3.asset->url
    }
  },
  "featuredArtist": featuredArtist->{
    name,
    role,
    "slug": slug.current,
    image,
    "bioExcerpt": pt::text(bio)
  },
  "featuredComposer": featuredComposer->{
    name,
    "slug": slug.current,
    birthYear,
    deathYear,
    image,
    "bioExcerpt": pt::text(bio)
  }
}
`);

const LATEST_RELEASES_QUERY = defineQuery(`
*[_type == "release"] | order(coalesce(releaseDate, "0000-01-01") desc) [0...8] {
  _id,
  name,
  albumArtist,
  catalogNo,
  releaseDate,
  "slug": slug.current,
  albumCover
}
`);

const LATEST_BLOGS_QUERY = defineQuery(`
*[_type == "blog"] | order(coalesce(publishDate, "0000-01-01") desc) [0...8] {
  _id,
  title,
  subtitle,
  author,
  publishDate,
  category,
  "slug": slug.current,
  featuredImage
}
`);

const HOME_UPCOMING_CONCERTS_QUERY = defineQuery(`
*[_type == "concert" && date >= $today]
{
  _id,
  title,
  subtitle,
  date,
  time,
  locationName,
  city,
  country,
  "artists": artists[]->{ _id, name, "slug": slug.current },
  ticketUrl
}
| order(date asc, time asc) [0...10]
`);

const getHomeSettings = cache(async () => {
  try {
    return await sanity.fetch<HomeSettings>(SETTINGS_QUERY);
  } catch (error) {
    console.error("Failed to fetch home settings:", error);
    return { featuredAlbum: null, featuredArtist: null, featuredComposer: null };
  }
});

export async function generateMetadata(): Promise<Metadata> {
  const { featuredAlbum: release } = await getHomeSettings();

  const description = release?.shortDescription ?? "Recording the extraordinary.";

  const ogImage = release?.albumCover
    ? urlFor(release.albumCover).width(1200).height(1200).url()
    : undefined;

  return {
    title: "TRPTK • Recording the extraordinary",
    description,
    alternates: { canonical: "/" },
    openGraph: {
      title: "TRPTK",
      description,
      type: "website",
      ...(ogImage && {
        images: [
          { url: ogImage, width: 1200, height: 1200, alt: "TRPTK • Recording the extraordinary" },
        ],
      }),
    },
    twitter: {
      card: "summary_large_image",
      title: "TRPTK",
      description,
      ...(ogImage && { images: [ogImage] }),
    },
  };
}

function cardVisibility(index: number) {
  if (index < 4) return "";
  if (index < 6) return "hidden md:block";
  return "hidden lg:block";
}

export default async function Home() {
  const today = new Date().toISOString().slice(0, 10);

  const [
    { featuredAlbum: release, featuredArtist: artist, featuredComposer: composer },
    latestReleases,
    latestBlogs,
    upcomingConcerts,
  ] = await Promise.all([
    getHomeSettings(),
    sanity.fetch<ReleaseCardData[]>(LATEST_RELEASES_QUERY),
    sanity.fetch<BlogCardData[]>(LATEST_BLOGS_QUERY),
    sanity.fetch<ConcertData[]>(HOME_UPCOMING_CONCERTS_QUERY, { today }),
  ]);

  const displayName = release?.name ?? "";
  const displayArtist = release?.albumArtist ?? "";

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "WebPage",
    name: "TRPTK",
    url: "https://trptk.com",
    description: "Recording the extraordinary.",
    ...(release && {
      mainEntity: {
        "@type": "MusicAlbum",
        name: release.name,
        ...(release.slug && { url: `https://trptk.com/release/${release.slug}` }),
        ...(release.albumArtist && {
          byArtist: { "@type": "MusicGroup", name: release.albumArtist },
        }),
        ...(release.albumCover && {
          image: urlFor(release.albumCover).width(800).url(),
        }),
      },
    }),
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c") }}
      />
      <Header />
      <section className="mx-auto my-auto max-w-250 px-6 py-12 font-silka md:px-8 md:py-16">
        {/* Featued Album */}
        {release && (
          <div className="mx-auto grid grid-cols-1 gap-10 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:gap-20">
            <div className="order-2 content-center sm:order-1">
              <h3 className="mb-2 font-silka text-sm break-words text-lightsec dark:text-darksec">
                Featured album
              </h3>
              {release.slug ? (
                <Link href={`/release/${release.slug}`}>
                  <h1 className="mb-2 font-argesta text-3xl break-words">{displayName}</h1>
                </Link>
              ) : (
                <h1 className="mb-2 font-argesta text-3xl break-words">{displayName}</h1>
              )}
              <h2 className="mb-6 font-silka text-base break-words text-lightsec dark:text-darksec">
                {displayArtist}
              </h2>
              {release.shortDescription && (
                <p className="line-clamp-2 text-sm md:line-clamp-3 lg:line-clamp-4">
                  {release.shortDescription}
                </p>
              )}
              {release.slug && (
                <FeaturedReleaseActions
                  tracks={release.tracks ?? []}
                  albumCover={release.albumCover}
                  albumArtist={release.albumArtist}
                  releaseSlug={release.slug}
                />
              )}
            </div>
            <div className="order-1 content-center sm:order-2">
              {release.slug ? (
                <Link href={`/release/${release.slug}`}>
                  <ReleaseCover
                    src={
                      release.albumCover ? urlFor(release.albumCover).url() : ARTIST_PLACEHOLDER_SRC
                    }
                    alt={`Album cover for ${displayName} by ${displayArtist}`}
                  />
                </Link>
              ) : (
                <ReleaseCover
                  src={
                    release.albumCover ? urlFor(release.albumCover).url() : ARTIST_PLACEHOLDER_SRC
                  }
                  alt={`Album cover for ${displayName} by ${displayArtist}`}
                />
              )}
            </div>
          </div>
        )}
      </section>

      {/* Latest releases */}
      {latestReleases.length > 0 && (
        <section className="mx-auto max-w-300 px-6 py-12 font-silka md:px-8 md:py-16 2xl:max-w-400">
          <h2 className="font-argesta text-3xl">Latest releases</h2>
          <ArrowLink
            href="/releases"
            className="mt-2 mb-8 inline-block text-sm text-lightsec dark:text-darksec"
          >
            Browse all releases
          </ArrowLink>

          <div className={CARD_GRID_CLASSES_4}>
            {latestReleases.map((r, i) => (
              <ReleaseCard key={r._id} release={r} className={cardVisibility(i)} />
            ))}
          </div>
        </section>
      )}

      {/* Featured Artist */}
      {artist && (
        <section className="mx-auto my-auto max-w-250 px-6 py-12 font-silka md:px-8 md:py-16">
          <div className="mx-auto grid grid-cols-1 gap-10 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:gap-20">
            <div className="content-center">
              {artist.slug ? (
                <Link href={`/artist/${artist.slug}`}>
                  <ReleaseCover
                    src={artist.image ? urlFor(artist.image).url() : ARTIST_PLACEHOLDER_SRC}
                    alt={`Photo of ${artist.name}`}
                  />
                </Link>
              ) : (
                <ReleaseCover
                  src={artist.image ? urlFor(artist.image).url() : ARTIST_PLACEHOLDER_SRC}
                  alt={`Photo of ${artist.name}`}
                />
              )}
            </div>
            <div className="content-center">
              <h3 className="mb-2 font-silka text-sm break-words text-lightsec dark:text-darksec">
                Featured artist
              </h3>
              {artist.slug ? (
                <Link href={`/artist/${artist.slug}`}>
                  <h2 className="mb-2 font-argesta text-3xl break-words">{artist.name}</h2>
                </Link>
              ) : (
                <h2 className="mb-2 font-argesta text-3xl break-words">{artist.name}</h2>
              )}
              <h3 className="mb-6 font-silka text-base break-words text-lightsec dark:text-darksec">
                {artist.role}
              </h3>
              {artist.bioExcerpt && (
                <p className="line-clamp-2 text-sm md:line-clamp-3 lg:line-clamp-4">
                  {artist.bioExcerpt}
                </p>
              )}
              {artist.slug && (
                <div className="mt-4 flex gap-3">
                  <IconButtonLink href={`/artist/${artist.slug}`} aria-label="View artist">
                    <IoPersonOutline />
                  </IconButtonLink>
                </div>
              )}
            </div>
          </div>
        </section>
      )}

      {/* From the blog */}
      {latestBlogs.length > 0 && (
        <section className="mx-auto max-w-300 px-6 py-12 font-silka md:px-8 md:py-16 2xl:max-w-400">
          <h2 className="font-argesta text-3xl">From the blog</h2>
          <ArrowLink
            href="/blog"
            className="mt-2 mb-8 inline-block text-sm text-lightsec dark:text-darksec"
          >
            Browse all posts
          </ArrowLink>

          <div className={CARD_GRID_CLASSES_4}>
            {latestBlogs.map((b, i) => (
              <BlogCard key={b._id} blog={b} className={cardVisibility(i)} />
            ))}
          </div>
        </section>
      )}

      {/* Featured Composer */}
      {composer && (
        <section className="mx-auto my-auto max-w-250 px-6 py-12 font-silka md:px-8 md:py-16">
          <div className="mx-auto grid grid-cols-1 gap-10 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:gap-20">
            <div className="order-2 content-center sm:order-1">
              <h3 className="mb-2 font-silka text-sm break-words text-lightsec dark:text-darksec">
                Featured composer
              </h3>
              {composer.slug ? (
                <Link href={`/composer/${composer.slug}`}>
                  <h2 className="mb-2 font-argesta text-3xl break-words">{composer.name}</h2>
                </Link>
              ) : (
                <h2 className="mb-2 font-argesta text-3xl break-words">{composer.name}</h2>
              )}
              <h3 className="mb-6 font-silka text-base break-words text-lightsec dark:text-darksec">
                {formatYears(composer.birthYear, composer.deathYear)}
              </h3>
              {composer.bioExcerpt && (
                <p className="line-clamp-2 text-sm md:line-clamp-3 lg:line-clamp-4">
                  {composer.bioExcerpt}
                </p>
              )}
              {composer.slug && (
                <div className="mt-4 flex gap-3">
                  <IconButtonLink href={`/composer/${composer.slug}`} aria-label="View composer">
                    <IoPersonOutline />
                  </IconButtonLink>
                </div>
              )}
            </div>
            <div className="order-1 content-center sm:order-2">
              {composer.slug ? (
                <Link href={`/composer/${composer.slug}`}>
                  <ReleaseCover
                    src={composer.image ? urlFor(composer.image).url() : ARTIST_PLACEHOLDER_SRC}
                    alt={`Portrait of ${composer.name}`}
                  />
                </Link>
              ) : (
                <ReleaseCover
                  src={composer.image ? urlFor(composer.image).url() : ARTIST_PLACEHOLDER_SRC}
                  alt={`Portrait of ${composer.name}`}
                />
              )}
            </div>
          </div>
        </section>
      )}

      {/* Upcoming concerts */}
      {upcomingConcerts.length > 0 && (
        <section className="mx-auto max-w-300 px-6 py-12 font-silka md:px-8 md:py-16 2xl:max-w-400">
          <h2 className="font-argesta text-3xl">Upcoming concerts</h2>
          <ArrowLink
            href="/concerts"
            className="mt-2 mb-8 inline-block text-sm text-lightsec dark:text-darksec"
          >
            Browse all concerts
          </ArrowLink>

          <ConcertTable concerts={upcomingConcerts} />
        </section>
      )}

      <Footer />
    </>
  );
}
