"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { AnimatePresence, motion, useScroll, useTransform } from "motion/react";
import { ArrowRight, Loader2 } from "lucide-react";
import type { ElementType } from "react";
import { siteConfig } from "@/lib/config/site";
import type { ProductTier, SimplePlan } from "@/lib/data/product-config";
import { cn } from "@/lib/utils";

const noiseStyle = {
  backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
  backgroundSize: "128px 128px",
};

type TierMap = Record<string, ProductTier>;

type ConfigOption = {
  label: string;
  description?: string;
  icon: ElementType;
  badge?: string;
};

type ConfigGroup = {
  label: string;
  options: ConfigOption[];
};

type SpecField = {
  key: keyof SimplePlan;
  label: string;
};

type ProductCatalogPageProps<T extends TierMap> = {
  tiers: T;
  defaultTier: keyof T & string;
  eyebrow: string;
  title: string;
  accentTitle: string;
  description: string;
  ctaLabel: string;
  configGroups: ConfigGroup[];
  specFields?: SpecField[];
  footerNote?: string;
};

const defaultSpecFields: SpecField[] = [
  { key: "cpu", label: "CPU" },
  { key: "ram", label: "RAM" },
  { key: "storage", label: "Storage" },
  { key: "bandwidth", label: "Network" },
];

function tierGlow(index: number) {
  const glows = [
    "radial-gradient(ellipse 60% 40% at 50% 0%, rgba(16,185,129,0.045) 0%, transparent 70%)",
    "radial-gradient(ellipse 60% 40% at 50% 0%, rgba(147,51,234,0.06) 0%, transparent 70%)",
    "radial-gradient(ellipse 60% 40% at 50% 0%, rgba(99,102,241,0.052) 0%, transparent 70%)",
    "radial-gradient(ellipse 60% 40% at 50% 0%, rgba(14,165,233,0.048) 0%, transparent 70%)",
  ];
  return glows[index % glows.length];
}

function PlanSpec({ field, plan }: { field: SpecField; plan: SimplePlan }) {
  const value = plan[field.key];

  if (!value) return null;

  return (
    <div className="rounded-lg border border-border/80 bg-elevated/60 px-3 py-2 shadow-[inset_0_1px_0_var(--depth-highlight)]">
      <div className="mb-1 text-[9px] font-black uppercase tracking-widest text-content-subtle">{field.label}</div>
      <p className="truncate text-xs font-semibold text-content-dim">{value}</p>
    </div>
  );
}

function ProductPlanCard({
  plan,
  index,
  activeTier,
  ctaLabel,
  specFields,
}: {
  plan: SimplePlan;
  index: number;
  activeTier: ProductTier;
  ctaLabel: string;
  specFields: SpecField[];
}) {
  return (
    <motion.article
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -10 }}
      transition={{ duration: 0.3, delay: index * 0.06 }}
      className="product-plan-card group relative flex min-h-[390px] flex-col overflow-hidden rounded-2xl border border-border/80 bg-surface transition-all duration-300 hover:-translate-y-1 hover:border-accent-hover/35"
    >
      <div className="relative shrink-0 overflow-hidden border-b border-border/70 bg-elevated/35 px-5 py-5">
        <div className="absolute inset-0 bg-[radial-gradient(circle_at_16%_0%,rgba(168,85,247,0.09),transparent_38%),linear-gradient(180deg,rgba(255,255,255,0.045),transparent_55%)]" />
        <div className="relative flex items-start justify-between gap-3">
          <div>
            <p className="text-[10px] font-black uppercase tracking-widest text-content-subtle">Starting from</p>
            <p className="mt-1 text-2xl font-black tracking-tight text-content">
              {plan.price}
              <span className="ml-1 text-[11px] font-bold text-content-subtle">/mo</span>
            </p>
          </div>
          {activeTier.badge && (
            <span className="rounded-full border border-accent-hover/25 bg-accent/10 px-2.5 py-1 text-[10px] font-black uppercase tracking-widest text-accent-text">
              {activeTier.badge}
            </span>
          )}
        </div>
      </div>

      <div className="flex flex-1 flex-col p-5">
        <div className="mb-5">
          <p className="text-[10px] font-black uppercase tracking-widest text-accent-text/90">{activeTier.label}</p>
          <h3 className="mt-1 text-lg font-black tracking-tight text-content transition-colors group-hover:text-accent-text">
            {plan.name}
          </h3>
        </div>

        <div className="mb-6 grid grid-cols-2 gap-2.5">
          {specFields.map((field) => (
            <PlanSpec key={field.key} field={field} plan={plan} />
          ))}
        </div>

        <a
          href={plan.billingUrl ?? siteConfig.billing.url}
          target="_blank"
          rel="noopener noreferrer"
          className="mt-auto flex w-full items-center justify-center gap-2 rounded-xl border border-accent/80 bg-accent px-4 py-3 text-sm font-black text-white transition-all duration-150 hover:-translate-y-0.5 hover:border-accent-hover hover:bg-accent-hover active:translate-y-1 active:shadow-none"
        >
          {ctaLabel}
          <ArrowRight className="h-3.5 w-3.5 opacity-70 transition-transform duration-200 group-hover:translate-x-0.5 group-hover:opacity-100" />
        </a>
      </div>
    </motion.article>
  );
}

export function ProductCatalogPage<T extends TierMap>({
  tiers,
  defaultTier,
  eyebrow,
  title,
  accentTitle,
  description,
  ctaLabel,
  configGroups,
  specFields = defaultSpecFields,
  footerNote,
}: ProductCatalogPageProps<T>) {
  const tierKeys = useMemo(() => Object.keys(tiers) as (keyof T & string)[], [tiers]);
  const [activeTier, setActiveTier] = useState<keyof T & string>(defaultTier);
  const [isVisible, setIsVisible] = useState(false);
  const [isTierSwitching, setIsTierSwitching] = useState(false);
  const [selectedConfig, setSelectedConfig] = useState(() =>
    Object.fromEntries(configGroups.map((group) => [group.label, group.options[0]?.label ?? ""]))
  );

  const containerRef = useRef<HTMLDivElement>(null);
  const { scrollYProgress } = useScroll({ target: containerRef, offset: ["start start", "end start"] });
  const headerOpacity = useTransform(scrollYProgress, [0, 0.2], [1, 0]);
  const headerY = useTransform(scrollYProgress, [0, 0.2], [0, -40]);

  useEffect(() => {
    const timer = setTimeout(() => setIsVisible(true), 100);
    return () => clearTimeout(timer);
  }, []);

  const activeIndex = Math.max(0, tierKeys.indexOf(activeTier));
  const currentTierData = tiers[activeTier] ?? tiers[defaultTier];
  const plans = currentTierData.plans;

  const handleTierChange = (newTier: keyof T & string) => {
    if (newTier === activeTier) return;
    setIsTierSwitching(true);
    setActiveTier(newTier);
    setTimeout(() => setIsTierSwitching(false), 350);
  };

  return (
    <main
      ref={containerRef}
      className={cn(
        "flex min-h-screen w-full flex-col items-center overflow-x-hidden bg-base font-sans text-content selection:bg-accent-hover/30",
        "transition-opacity duration-700",
        isVisible ? "opacity-100" : "opacity-0"
      )}
    >
      <div className="fixed inset-0 z-0 pointer-events-none opacity-[0.025]" style={noiseStyle} />
      <div className="fixed inset-0 z-0 pointer-events-none">
        <motion.div
          animate={{ background: tierGlow(activeIndex) }}
          transition={{ duration: 0.8 }}
          className="absolute inset-0"
        />
      </div>

      <div className="relative z-10 w-full max-w-7xl px-4 pb-24 pt-32 md:px-6">
        <motion.div style={{ opacity: headerOpacity, y: headerY }} className="mb-14 flex flex-col items-center text-center">
          <div className="mb-6 flex items-center justify-center gap-3">
            <span className="block h-0.5 w-6 rounded-full bg-accent-hover" />
            <p className="text-xs font-bold uppercase tracking-widest text-accent-text">{eyebrow}</p>
            <span className="block h-0.5 w-6 rounded-full bg-accent-hover" />
          </div>
          <h1 className="mb-5 text-5xl font-semibold leading-[1.05] tracking-tight text-content md:text-6xl lg:text-7xl">
            {title} <br />
            <span className="text-accent-text">{accentTitle}</span>
          </h1>
          <p className="max-w-2xl text-[1rem] leading-relaxed text-content-dim md:text-lg">{description}</p>
        </motion.div>

        <div className="sticky top-24 z-40 mb-8 flex w-full flex-col items-center gap-4">
          <div className="flex max-w-full justify-center gap-1 overflow-x-auto rounded-xl border border-border/80 bg-surface/90 p-1.5 shadow-2xl backdrop-blur-xl">
            {tierKeys.map((tierKey) => {
              const tier = tiers[tierKey];
              const Icon = tier.icon;
              const isActive = activeTier === tierKey;
              return (
                <button
                  key={tierKey}
                  onClick={() => handleTierChange(tierKey)}
                  className={cn(
                    "relative flex min-w-max items-center gap-2 rounded-lg px-5 py-2.5 text-sm font-semibold transition-all duration-200",
                    isActive ? "bg-accent text-white" : "text-content-dim hover:bg-elevated hover:text-content"
                  )}
                >
                  <Icon className="h-4 w-4" />
                  {tier.label}
                  {tier.badge && (
                    <span className={cn(
                      "rounded px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wide",
                      isActive ? "bg-white/20 text-white" : "bg-elevated text-content-muted"
                    )}>
                      {tier.badge}
                    </span>
                  )}
                </button>
              );
            })}
          </div>

          <motion.div
            key={activeTier}
            initial={{ opacity: 0, y: -8 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.25 }}
            className="max-w-3xl rounded-xl border border-border/80 bg-surface/90 px-5 py-3 text-center text-sm text-content-muted backdrop-blur-md"
          >
            {currentTierData.desc}
          </motion.div>
        </div>

        <div className="mb-8">
          <div className="grid gap-3 md:grid-cols-2">
            {configGroups.map((group) => (
              <div key={group.label} className="rounded-2xl border border-border/80 bg-surface p-3">
                <p className="mb-2 px-1 text-[10px] font-black uppercase tracking-widest text-content-subtle">{group.label}</p>
                <div className="grid gap-2">
                  {group.options.map((option) => {
                    const Icon = option.icon;
                    const isActive = selectedConfig[group.label] === option.label;
                    return (
                      <button
                        key={option.label}
                        onClick={() => setSelectedConfig((prev) => ({ ...prev, [group.label]: option.label }))}
                        className={cn(
                          "flex items-center gap-3 rounded-xl border px-3 py-2.5 text-left transition-all duration-200",
                          isActive
                            ? "border-accent-hover/40 bg-accent/10 text-content"
                            : "border-border/80 bg-elevated/45 text-content-dim hover:border-border-hover hover:text-content"
                        )}
                      >
                        <Icon className="h-4 w-4 shrink-0 text-accent-text" />
                        <span className="min-w-0 flex-1">
                          <span className="flex items-center gap-2 text-sm font-semibold">
                            {option.label}
                            {option.badge && (
                              <span className="rounded-full border border-accent-hover/20 bg-accent/10 px-1.5 py-0.5 text-[9px] font-black uppercase tracking-wide text-accent-text">
                                {option.badge}
                              </span>
                            )}
                          </span>
                          {option.description && (
                            <span className="mt-0.5 block text-xs leading-relaxed text-content-muted">{option.description}</span>
                          )}
                        </span>
                      </button>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </div>

        <AnimatePresence mode="wait">
          {isTierSwitching ? (
            <motion.div key="loading" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex justify-center py-32">
              <div className="flex flex-col items-center gap-4">
                <Loader2 className="h-8 w-8 animate-spin text-accent-text" />
                <p className="text-sm text-content-subtle">Loading plans...</p>
              </div>
            </motion.div>
          ) : (
            <motion.div
              key="content"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              className="grid w-full grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3"
            >
              {plans.length > 0 ? (
                plans.map((plan, index) => (
                  <ProductPlanCard
                    key={`${activeTier}-${plan.id}`}
                    plan={plan}
                    index={index}
                    activeTier={currentTierData}
                    ctaLabel={ctaLabel}
                    specFields={specFields}
                  />
                ))
              ) : (
                <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="col-span-full flex flex-col items-center justify-center py-24 text-center">
                  <h3 className="mb-1 text-lg font-semibold text-content-dim">No plans found</h3>
                  <p className="text-sm text-content-subtle">Switch tiers or check back later.</p>
                </motion.div>
              )}
            </motion.div>
          )}
        </AnimatePresence>

        {footerNote && <p className="mt-8 text-center text-xs text-content-faint">{footerNote}</p>}
      </div>
    </main>
  );
}
