import { Link } from "react-router-dom";
import { motion } from "framer-motion";
import { ArrowLeft } from "lucide-react";
import orionLogo from "@/assets/orion-logo.svg";
import { looksLikeImageUrl } from "@/lib/contentFormUtils";
import {
  getCompetitionNavigation,
  type CompetitionNavItem,
} from "@/lib/competitionNavigation";

type Content = Record<string, unknown>;

export interface GradeHeroButton {
  id: string;
  label: string;
  icon: string;
  href: string;
  variant: "primary" | "secondary";
}

export type { CompetitionNavItem };

export interface GradeHeroStatistic {
  value: string;
  label: string;
}

export interface GradeHeroIcon {
  emoji: string;
  image: string;
}

function stringValue(value: unknown): string {
  return typeof value === "string" ? value : "";
}

function optionalString(content: Content | undefined, key: string, fallback = ""): string {
  return key in (content ?? {}) ? stringValue(content?.[key]).trim() : fallback;
}

function normalizeTextItems(value: unknown): string[] {
  if (!Array.isArray(value)) return [];

  return value
    .map((item) => (
      typeof item === "string"
        ? item
        : stringValue((item as { label?: unknown; text?: unknown })?.label)
          || stringValue((item as { text?: unknown })?.text)
    ))
    .map((item) => item.trim())
    .filter(Boolean);
}

export function getHeroFeatureHighlights(content?: Content): string[] {
  const rawHighlights = Array.isArray(content?.featureHighlights)
    ? content.featureHighlights
    : Array.isArray(content?.pills)
      ? content.pills
      : [];

  return normalizeTextItems(rawHighlights);
}

export function getHeroButtons(content?: Content): GradeHeroButton[] {
  if (!Array.isArray(content?.buttons)) return [];

  return content.buttons
    .map((item, index) => {
      const button = typeof item === "string"
        ? { label: item }
        : item as Record<string, unknown>;
      const label = stringValue(button.label).trim();

      return {
        id: stringValue(button.id).trim() || `button-${index + 1}`,
        label,
        icon: stringValue(button.icon).trim(),
        href: stringValue(button.href).trim(),
        variant: button.variant === "primary" ? "primary" as const : "secondary" as const,
      };
    })
    .filter((button) => button.label);
}

export function getHeroStatistics(content?: Content): GradeHeroStatistic[] {
  if (!Array.isArray(content?.statistics)) return [];

  return content.statistics
    .map((item) => {
      if (typeof item === "string") {
        return { value: "", label: item.trim() };
      }

      const statistic = item as Record<string, unknown>;
      return {
        value: stringValue(statistic.value).trim(),
        label: stringValue(statistic.label).trim(),
      };
    })
    .filter((statistic) => statistic.value || statistic.label);
}

export function getGradeHeroIcon(content?: Content): GradeHeroIcon {
  const image = [
    content?.heroIconImage,
    content?.mainIconImage,
    content?.iconImage,
    content?.iconUrl,
  ]
    .map(stringValue)
    .map((value) => value.trim())
    .find(Boolean) ?? "";
  const emoji = [
    content?.heroIconEmoji,
    content?.mainIcon,
    content?.emoji,
    content?.icon,
  ]
    .map(stringValue)
    .map((value) => value.trim())
    .find(Boolean) ?? "";

  if (!image && looksLikeImageUrl(emoji)) {
    return { emoji: "", image: emoji };
  }

  return { emoji, image };
}

export function normalizeGradeHeroContent(content: Content = {}): Content {
  const heroIcon = getGradeHeroIcon(content);
  const normalized: Content = {
    ...content,
    heroIconEmoji: heroIcon.emoji,
    heroIconImage: heroIcon.image,
    featureHighlights: getHeroFeatureHighlights(content),
    buttons: getHeroButtons(content),
    competitionNavigation: getCompetitionNavigation(content),
    badges: normalizeTextItems(content.badges),
    statistics: getHeroStatistics(content),
  };
  delete normalized.pills;
  delete normalized.mainIcon;
  delete normalized.mainIconImage;

  return normalized;
}

const defaultBackLabel = "SPARK Dashboard";
const defaultBackHref = "/";
const defaultLogoAlt = "Orion";
const defaultTitle = "Kindergarten";

export function GradeHeroBlock({
  content,
  activeButtonId,
  onButtonClick,
  activeCompetitionNavId,
  onCompetitionNavClick,
}: {
  content?: Content;
  activeButtonId?: string;
  onButtonClick?: (button: GradeHeroButton) => void;
  activeCompetitionNavId?: string;
  onCompetitionNavClick?: (item: CompetitionNavItem) => void;
}) {
  const layout = content?.layout === "detail" ? "detail" : "brand";
  const backLabel = optionalString(content, "backLabel", defaultBackLabel);
  const backHref = optionalString(content, "backHref", defaultBackHref);
  const logoSrc = stringValue(content?.logoSrc).trim() || orionLogo;
  const logoAlt = optionalString(content, "logoAlt", defaultLogoAlt);
  const heroIcon = getGradeHeroIcon(content);
  const smallLabel = optionalString(content, "smallLabel");
  const title = optionalString(content, "title", defaultTitle);
  // Subtitle default lives only in component library seed (new instances).
  // Never inject a render-time fallback — empty/cleared values must hide the subtitle.
  const subtitle = optionalString(content, "subtitle");
  const description = optionalString(content, "description");
  const themeLabel = optionalString(content, "themeLabel");
  const themeLine = optionalString(content, "themeLine");
  const featureHighlights = getHeroFeatureHighlights(content);
  // Keep labeled nav rows in the preview even before Target Component is chosen.
  const competitionNavigation = getCompetitionNavigation(content);
  const buttons = getHeroButtons(content);
  const showCompetitionNavigation = Array.isArray(content?.competitionNavigation)
    && competitionNavigation.length > 0;
  const badges = normalizeTextItems(content?.badges);
  const statistics = getHeroStatistics(content);
  const legacyDesignHero = Array.isArray(content?.pills);
  const titleSize = content?.titleSize === "compact" || legacyDesignHero ? "compact" : "standard";
  const showBackButton = content?.showBackButton !== false;
  const showLogo = content?.showLogo !== false;
  const showDecorations = content?.showBackgroundDecorations !== false;
  const backgroundPattern = optionalString(
    content,
    "backgroundPattern",
    layout === "detail" ? "radial" : "rays"
  );
  const backgroundImage = optionalString(content, "backgroundImage");
  const accentColor = optionalString(content, "accentColor", "deep-sea").replace(/[^a-z0-9-]/gi, "") || "deep-sea";
  const patternPosition = optionalString(content, "patternPosition", "50% 50%");
  const overlayOpacityValue = Number(content?.overlayOpacity);
  const overlayOpacity = Number.isFinite(overlayOpacityValue)
    ? Math.min(1, Math.max(0, overlayOpacityValue))
    : 0.35;
  const showOverlay = content?.showOverlay !== false;
  const rayCountValue = Number(content?.rayCount);
  const rayCount = Number.isFinite(rayCountValue)
    ? Math.min(24, Math.max(1, Math.round(rayCountValue)))
    : legacyDesignHero ? 9 : 6;
  const sectionStyle = backgroundImage
    ? { backgroundImage: `url("${backgroundImage.replace(/"/g, "%22")}")` }
    : undefined;

  return (
    <section
      className={`relative bg-bark bg-cover bg-center text-center overflow-hidden ${layout === "detail" ? "py-16" : "py-14 md:py-20"}`}
      style={sectionStyle}
    >
      {backgroundImage && showOverlay && (
        <div className="absolute inset-0 bg-bark" style={{ opacity: overlayOpacity }} />
      )}
      {showDecorations && backgroundPattern === "rays" && (
        <div className="absolute inset-0 opacity-[0.06]">
          <svg className="w-full h-full" viewBox="0 0 800 400" aria-hidden>
            {Array.from({ length: rayCount }, (_, index) => index * (360 / rayCount)).map((angle) => (
              <line
                key={angle}
                x1={400}
                y1={200}
                x2={400 + 400 * Math.cos((angle * Math.PI) / 180)}
                y2={200 + 400 * Math.sin((angle * Math.PI) / 180)}
                stroke="white"
                strokeWidth={0.5}
              />
            ))}
          </svg>
        </div>
      )}
      {showDecorations && backgroundPattern === "radial" && (
        <div
          className="absolute inset-0"
          style={{
            background: `radial-gradient(circle at ${patternPosition}, hsl(var(--${accentColor}) / 0.2), transparent 60%)`,
          }}
        />
      )}
      <div className="relative z-10 container mx-auto px-6">
        {showBackButton && backLabel && backHref && (
          <Link
            to={backHref}
            className="inline-flex items-center gap-2 text-milk/60 hover:text-milk font-display text-sm mb-6 transition-colors"
          >
            <ArrowLeft className="w-4 h-4" /> {backLabel}
          </Link>
        )}
        {showLogo && (
          <motion.div
            initial={{ opacity: 0, scale: 0.9 }}
            animate={{ opacity: 1, scale: 1 }}
            transition={{ duration: 0.5 }}
          >
            <img src={logoSrc} alt={logoAlt} className="h-12 md:h-16 mx-auto mb-4" />
          </motion.div>
        )}
        {(heroIcon.image || heroIcon.emoji) && (
          <motion.div
            className="mb-4"
            initial={{ opacity: 0, scale: 0.9 }}
            animate={{ opacity: 1, scale: 1 }}
            transition={{ duration: 0.5 }}
          >
            {heroIcon.image ? (
              <img
                src={heroIcon.image}
                alt=""
                className="h-16 w-16 object-contain mx-auto"
                aria-hidden
              />
            ) : (
              <span className="text-5xl block" aria-hidden>{heroIcon.emoji}</span>
            )}
          </motion.div>
        )}
        <motion.h1
          className={`font-display font-bold text-milk ${
            layout === "detail"
              ? "text-4xl md:text-5xl mb-2"
              : titleSize === "compact"
                ? "text-3xl md:text-5xl mb-3"
                : "text-4xl md:text-6xl mb-3"
          }`}
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 0.1 }}
        >
          {title}
        </motion.h1>
        {subtitle && (
          <motion.p
            className={`font-display mx-auto ${
              layout === "detail"
                ? "text-lg text-milk/60 max-w-2xl"
                : titleSize === "compact"
                  ? "text-base md:text-lg text-milk/70 max-w-xl"
                  : "text-lg text-milk/70 max-w-lg"
            }`}
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.25 }}
          >
            {subtitle}
          </motion.p>
        )}
        {description && (
          <motion.p
            className="text-milk/50 text-sm mt-2 max-w-2xl mx-auto"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.3 }}
          >
            {description}
          </motion.p>
        )}
        {smallLabel && (
          <motion.p
            className="font-display text-sm text-milk/40 mt-2"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.31 }}
          >
            {smallLabel}
          </motion.p>
        )}
        {statistics.length > 0 && (
          <motion.div
            className="flex flex-wrap justify-center gap-x-5 gap-y-2 mt-3 text-milk/50 text-sm"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.32 }}
          >
            {statistics.map((statistic, index) => (
              <span key={`${statistic.value}-${statistic.label}-${index}`}>
                {statistic.value && <strong className="font-display text-milk/80">{statistic.value}</strong>}
                {statistic.value && statistic.label ? " " : ""}
                {statistic.label}
              </span>
            ))}
          </motion.div>
        )}
        {(themeLabel || themeLine) && (
          <motion.div
            className="mt-4 font-display"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.33 }}
          >
            {themeLabel && <span className="text-xs text-milk/45 block">{themeLabel}</span>}
            {themeLine && <span className="text-sm font-semibold text-milk/80 block mt-0.5">{themeLine}</span>}
          </motion.div>
        )}
        {badges.length > 0 && (
          <motion.div
            className="flex flex-wrap justify-center gap-2 mt-4"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.34 }}
          >
            {badges.map((badge, index) => (
              <span
                key={`${badge}-${index}`}
                className="text-xs font-display px-3 py-1 rounded-full bg-milk/10 text-milk/70"
              >
                {badge}
              </span>
            ))}
          </motion.div>
        )}
        {featureHighlights.length > 0 && (
          <motion.div
            className="flex flex-wrap justify-center gap-3 mt-5"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.35 }}
          >
            {featureHighlights.map((highlight, index) => (
              <span
                key={`${highlight}-${index}`}
                className="text-[11px] font-display font-bold tracking-wider uppercase px-3 py-1 rounded-full bg-milk/10 text-milk/80 border border-milk/20"
              >
                {highlight}
              </span>
            ))}
          </motion.div>
        )}
        {showCompetitionNavigation ? (
          <motion.div
            className="flex flex-wrap justify-center gap-2 mt-8"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.4 }}
          >
            {competitionNavigation.map((item, index) => {
              const active =
                activeCompetitionNavId === item.id
                || (!activeCompetitionNavId && index === 0);
              const className = `font-display text-sm px-5 py-2 rounded-full transition-all ${
                active
                  ? "bg-sunflower text-bark font-bold"
                  : "bg-milk/10 text-milk/60 hover:bg-milk/20"
              }`;
              const countLabel = item.badgeCount ? ` (${item.badgeCount})` : "";

              return (
                <button
                  key={item.id}
                  type="button"
                  className={className}
                  onClick={() => onCompetitionNavClick?.(item)}
                >
                  {item.icon ? <span aria-hidden>{item.icon} </span> : null}
                  {item.label}
                  {countLabel}
                </button>
              );
            })}
          </motion.div>
        ) : buttons.length > 0 ? (
          <motion.div
            className="flex flex-wrap justify-center gap-2 mt-8"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.4 }}
          >
            {buttons.map((button) => {
              const active = activeButtonId === button.id || (!activeButtonId && button.variant === "primary");
              const className = `font-display text-sm px-5 py-2 rounded-full transition-all ${
                active
                  ? "bg-sunflower text-bark font-bold"
                  : "bg-milk/10 text-milk/60 hover:bg-milk/20"
              }`;
              const label = <>{button.icon && <span aria-hidden>{button.icon} </span>}{button.label}</>;

              if (button.href) {
                return button.href.startsWith("http") ? (
                  <a key={button.id} href={button.href} className={className}>
                    {label}
                  </a>
                ) : (
                  <Link key={button.id} to={button.href} className={className}>
                    {label}
                  </Link>
                );
              }

              return (
                <button
                  key={button.id}
                  type="button"
                  className={className}
                  onClick={() => onButtonClick?.(button)}
                >
                  {label}
                </button>
              );
            })}
          </motion.div>
        ) : null}
      </div>
    </section>
  );
}
