import Image from "next/image";
import { playfair as serif } from "@/lib/fonts";
import HeroAnimatedHeader from "./HeroAnimatedHeader.client";
import HeroTooltipLoader from "./HeroTooltipLoader.client";

import {
  type RichTextRoot,
  renderLexical,
  extractPlainText,
} from "../utils";

type MediaSizes = {
  small?: { url?: string | null };
  medium?: { url?: string | null };
  large?: { url?: string | null };
  og?: { url?: string | null };
};

type MediaDocument = {
  url?: string | null;
  alt?: string | null;
  sizes?: MediaSizes | null;
};

type HeroOfferBlock = {
  type?: string;
  props?: {
    variant?: string | null;
    headline?: string | RichTextRoot | null;
    subheadline?: string | RichTextRoot | null;
    inclusionText?: string | RichTextRoot | null;
    desktopImageId?: number | null;
    mobileImageId?: number | null;
    price?: {
      prefix?: string | null;
      amount?: string | null;
      suffix?: string | null;
    } | null;
    meta?: {
      anchorId?: string | null;
    } | null;
  } | null;
};

type HeaderNavItem = {
  id?: string | number;
  label?: string | null;
  href?: string | null;
  openInNewTab?: boolean | null;
};

type HeaderGlobal = {
  logo?: number | null;
  navItems?: HeaderNavItem[] | null;
};

type ScillyPageData = {
  layout?: HeroOfferBlock[];
  included?: {
    media?: Record<string, MediaDocument>;
    globals?: {
      header?: HeaderGlobal | null;
    } | null;
  } | null;
};

const CMS_BASE_URL =
  process.env.NEXT_PUBLIC_CMS_BASE_URL?.replace(/\/$/, "") ?? "";

function isHeroBlock(block: HeroOfferBlock | undefined): block is HeroOfferBlock {
  return block?.type === "heroOfferV1" && block?.props?.variant === "hero";
}

function toAbsoluteUrl(url?: string | null) {
  if (!url) return null;
  if (url.startsWith("http://") || url.startsWith("https://")) return url;
  if (!CMS_BASE_URL || !url.startsWith("/")) return url;
  return `${CMS_BASE_URL}${url}`;
}

function resolvePreferredImageUrl(media: MediaDocument | null) {
  return toAbsoluteUrl(
    media?.sizes?.large?.url ??
      media?.sizes?.medium?.url ??
      media?.sizes?.small?.url ??
      media?.url,
  );
}

function resolveMobileImageUrl(media: MediaDocument | null) {
  return toAbsoluteUrl(
    media?.sizes?.medium?.url ??
      media?.sizes?.small?.url ??
      media?.sizes?.large?.url ??
      media?.url,
  );
}

function splitPriceSuffix(value?: string | null) {
  const parts = value?.trim().split(/\s+/).filter(Boolean) ?? [];
  if (parts.length === 0) return ["", ""] as const;
  if (parts.length === 1) return [parts[0], ""] as const;
  return [parts[0], parts.slice(1).join(" ")] as const;
}

export default function Hero({ data }: { data: ScillyPageData }) {
  const heroBlock = data.layout?.find(isHeroBlock);
  if (!heroBlock?.props) return null;

  const mediaMap = data.included?.media ?? {};
  const header = data.included?.globals?.header ?? null;
  const logoMedia = header?.logo != null ? (mediaMap[String(header.logo)] ?? null) : null;
  const logoSrc = resolvePreferredImageUrl(logoMedia);
  const navItems = header?.navItems ?? [];

  const desktopImage =
    heroBlock.props.desktopImageId != null
      ? (mediaMap[String(heroBlock.props.desktopImageId)] ?? null)
      : null;

  const mobileImage =
    heroBlock.props.mobileImageId != null
      ? (mediaMap[String(heroBlock.props.mobileImageId)] ?? null)
      : null;

  const desktopImageSrc = resolvePreferredImageUrl(desktopImage);
  const mobileImageSrc = resolveMobileImageUrl(mobileImage) ?? desktopImageSrc;

  const headline = heroBlock.props.headline;
  const subheadline = heroBlock.props.subheadline;
  const inclusionText = heroBlock.props.inclusionText;
  const pricePrefix = heroBlock.props.price?.prefix?.trim() ?? "";
  const priceAmount = heroBlock.props.price?.amount?.trim() ?? "";
  const priceSuffix = heroBlock.props.price?.suffix?.trim() ?? "";

  const [suffixTop, suffixBottom] = splitPriceSuffix(priceSuffix);
  const hasPrice = Boolean(pricePrefix || priceAmount || priceSuffix);

  const heroAlt =
    desktopImage?.alt?.trim() ||
    mobileImage?.alt?.trim() ||
    extractPlainText(headline) ||
    "Hero image";

  return (
    <section
      id={heroBlock.props.meta?.anchorId ?? undefined}
      className="relative h-[100vh] w-full overflow-hidden text-white sm:h-auto sm:max-h-[100vh] sm:aspect-[1440/800]"
    >
      {desktopImageSrc && (
        <Image
          src={desktopImageSrc}
          alt={heroAlt}
          fill
          priority
          fetchPriority="high"
          className="hidden object-cover sm:block"
          sizes="(min-width: 640px) 100vw, 1px"
        />
      )}

      {mobileImageSrc && (
        <Image
          src={mobileImageSrc}
          alt={heroAlt}
          fill
          priority
          fetchPriority="high"
          className="block object-cover sm:hidden"
          sizes="(max-width: 640px) 100vw, 1px"
        />
      )}

      <HeroTooltipLoader alt={heroAlt} />

      <HeroAnimatedHeader
        logoSrc={logoSrc}
        logoAlt={logoMedia?.alt || "Karma Group Logo"}
        navItems={navItems}
      />

      <div
        className="
          absolute z-[20] -translate-y-1/2
          left-[64px] right-[64px] top-[75%]
          sm:left-[40px] sm:right-[40px] sm:top-[75%]
          md:left-[80px] md:right-auto md:w-[420px]
          lg:left-[182px] lg:top-[75%] lg:w-[625px]
        "
      >
        {headline && (
          <h1 className="sr-only">{extractPlainText(headline)}</h1>
        )}

        {hasPrice || inclusionText ? (
          <div className="flex flex-col items-center gap-[12px] sm:items-start sm:gap-[8px]">
            <div className="flex flex-col items-center gap-[10px] sm:flex-row sm:items-end sm:gap-[18px]">
              {hasPrice ? (
                <div>
                  {pricePrefix ? (
                    <div
                      className={`text-[25px] leading-[1.2] sm:text-[18px] lg:text-[23px] ${serif.className}`}
                    >
                      {pricePrefix}
                    </div>
                  ) : null}

                  <div className="mt-[6px] flex items-end gap-[6px]">
                    {priceAmount ? (
                      <span
                        className={`text-[70px] font-bold leading-[100%] text-[#FF8F00] sm:text-[50px] lg:text-[63px] ${serif.className}`}
                      >
                        {priceAmount}
                      </span>
                    ) : null}

                    {priceSuffix ? (
                      <div className="flex flex-col items-center leading-none">
                        <span
                          className={`text-[44px] sm:text-[30px] lg:text-[40px] ${serif.className}`}
                        >
                          {suffixTop}
                        </span>
                        {suffixBottom ? (
                          <span
                            className={`text-[25px] sm:text-[20px] lg:text-[23px] ${serif.className}`}
                          >
                            {suffixBottom}
                          </span>
                        ) : null}
                      </div>
                    ) : null}
                  </div>
                </div>
              ) : null}

              {hasPrice && inclusionText ? (
                <span
                  className={`
                    flex h-[40px] items-center justify-center
                    text-[45px] leading-[1]
                    sm:h-auto sm:text-[28px] lg:text-[40px]
                    ${serif.className}
                  `}
                >
                  +
                </span>
              ) : null}

              {inclusionText ? (
                <div
                  className={`px-[41px] text-center text-[34px] leading-none sm:px-0 sm:text-left sm:text-[22px] sm:w-max lg:text-[31px] ${serif.className}`}
                >
                  {typeof inclusionText === "string" ? (
                    <>
                      {inclusionText.split(" ")[0]}
                      <br />
                      {inclusionText.split(" ").slice(1).join(" ")}
                    </>
                  ) : (
                    renderLexical(inclusionText)
                  )}
                </div>
              ) : null}
            </div>
          </div>
        ) : null}

        {subheadline ? (
          <div className="mx-auto mt-[12px] text-center text-[14px] tracking-[0.05em] sm:mx-0 sm:mt-[15px] sm:text-left sm:text-[14px] lg:text-[19px]">
            {renderLexical(subheadline)}
          </div>
        ) : null}
      </div>
    </section>
  );
}
