"use client";

import { cn } from "@/lib/utils";
import gsap from "gsap";
import { useLayoutEffect, useRef } from "react";
import { AnimatedCounter } from "./animated-counter";
import { SparkleIcon } from "./icons";
import { LiveClock } from "./live-clock";

type Props = {
  total: number;
  active: number;
  closingSoon: number;
  isLoading: boolean;
};

function greeting() {
  const h = new Date().getHours();
  if (h < 5) return "Working late";
  if (h < 12) return "Good morning";
  if (h < 17) return "Good afternoon";
  if (h < 21) return "Good evening";
  return "Good night";
}

export function DashboardHero({
  total,
  active,
  closingSoon,
  isLoading,
}: Props) {
  const rootRef = useRef<HTMLDivElement>(null);
  const auroraRef = useRef<HTMLDivElement>(null);
  const orbARef = useRef<HTMLDivElement>(null);
  const orbBRef = useRef<HTMLDivElement>(null);
  const orbCRef = useRef<HTMLDivElement>(null);
  const titleRef = useRef<HTMLHeadingElement>(null);
  const shineRef = useRef<HTMLSpanElement>(null);

  useLayoutEffect(() => {
    const reduced =
      typeof window !== "undefined" &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    const resetIntroTargets = () => {
      const root = rootRef.current;
      if (root) {
        gsap.killTweensOf(root);
        gsap.set(root, { clearProps: "opacity,transform" });
      }
      const title = titleRef.current;
      if (title) {
        const inner = title.querySelector<HTMLElement>("[data-title-inner]");
        if (inner) {
          gsap.killTweensOf(inner);
          gsap.set(inner, { clearProps: "opacity,transform" });
        }
      }
      root?.querySelectorAll<HTMLElement>("[data-hero-pill]").forEach((el) => {
        gsap.killTweensOf(el);
        gsap.set(el, { clearProps: "opacity,transform,scale" });
      });
    };

    const ctx = gsap.context(() => {
      if (reduced) return;

      const root = rootRef.current;
      if (root) {
        // Do not tween root opacity: Strict Mode + revert can leave the whole hero
        // at opacity 0. Motion uses translateY only.
        gsap.fromTo(
          root,
          { y: 28 },
          {
            y: 0,
            duration: 0.8,
            ease: "power3.out",
          },
        );
      }

      // Animate a wrapper around the headline, not per-glyph. Transforms on
      // children inside `bg-clip-text` / `text-transparent` often paint as fully
      // invisible in WebKit and some Chromium builds.
      const titleInner = titleRef.current?.querySelector<HTMLElement>(
        "[data-title-inner]",
      );
      if (titleInner) {
        gsap.fromTo(
          titleInner,
          { y: 36 },
          {
            y: 0,
            duration: 0.75,
            ease: "back.out(1.7)",
            delay: 0.2,
          },
        );
      }

      const pills = rootRef.current?.querySelectorAll<HTMLElement>("[data-hero-pill]");
      if (pills?.length) {
        gsap.fromTo(
          pills,
          { y: 16, scale: 0.92 },
          {
            y: 0,
            scale: 1,
            duration: 0.55,
            stagger: 0.08,
            delay: 0.55,
            ease: "back.out(1.6)",
          },
        );
      }

      if (auroraRef.current) {
        gsap.to(auroraRef.current, {
          rotate: 360,
          duration: 42,
          ease: "none",
          repeat: -1,
        });
      }

      if (orbARef.current) {
        gsap.to(orbARef.current, {
          x: 42,
          y: -26,
          scale: 1.18,
          duration: 7,
          repeat: -1,
          yoyo: true,
          ease: "sine.inOut",
        });
      }
      if (orbBRef.current) {
        gsap.to(orbBRef.current, {
          x: -32,
          y: 24,
          scale: 1.12,
          duration: 8,
          repeat: -1,
          yoyo: true,
          ease: "sine.inOut",
        });
      }
      if (orbCRef.current) {
        gsap.to(orbCRef.current, {
          x: 22,
          y: 18,
          scale: 1.08,
          duration: 9.5,
          repeat: -1,
          yoyo: true,
          ease: "sine.inOut",
        });
      }

      if (shineRef.current) {
        const shineTl = gsap.timeline({ repeat: -1, repeatDelay: 3.5 });
        shineTl
          .set(shineRef.current, { xPercent: -160, opacity: 0 })
          .to(shineRef.current, {
            opacity: 1,
            duration: 0.2,
            delay: 1.8,
          })
          .to(
            shineRef.current,
            {
              xPercent: 260,
              duration: 1.8,
              ease: "power2.inOut",
            },
            "<",
          )
          .to(shineRef.current, { opacity: 0, duration: 0.2 });
      }

      if (!root) return;
      const onMove = (e: MouseEvent) => {
        const r = root.getBoundingClientRect();
        const px = (e.clientX - r.left) / r.width - 0.5;
        const py = (e.clientY - r.top) / r.height - 0.5;
        gsap.to(orbARef.current, {
          xPercent: px * 22,
          yPercent: py * 18,
          duration: 1.2,
          ease: "power2.out",
        });
        gsap.to(orbBRef.current, {
          xPercent: px * -18,
          yPercent: py * 20,
          duration: 1.3,
          ease: "power2.out",
        });
        gsap.to(orbCRef.current, {
          xPercent: px * 12,
          yPercent: py * -14,
          duration: 1.4,
          ease: "power2.out",
        });
      };
      root.addEventListener("mousemove", onMove);
      return () => root.removeEventListener("mousemove", onMove);
    }, rootRef);

    return () => {
      const root = rootRef.current;
      const title = titleRef.current;
      const titleInner = title?.querySelector<HTMLElement>("[data-title-inner]");
      if (titleInner) gsap.killTweensOf(titleInner);
      if (root) gsap.killTweensOf(root);
      root
        ?.querySelectorAll<HTMLElement>("[data-hero-pill]")
        .forEach((el) => gsap.killTweensOf(el));
      ctx.revert();
      // React Strict Mode remounts before intro tweens finish; revert can leave
      // inline opacity/transform stuck (invisible headline / blank hero).
      resetIntroTargets();
    };
  }, []);

  const headline = `${greeting()}, welcome to OppLens`;
  const sub = "Real-time pulse on every tender flowing through your pipeline.";

  return (
    <div
      ref={rootRef}
      className="relative isolate overflow-hidden rounded-3xl border border-stroke/70 bg-gradient-to-br from-slate-50 via-white to-violet-50/40 p-6 text-slate-900 shadow-1 md:p-8 lg:p-10 dark:border-transparent dark:bg-[#0A0E1E] dark:bg-none dark:text-white dark:shadow-card"
    >
      <div
        ref={auroraRef}
        aria-hidden
        className="pointer-events-none absolute -inset-[40%] z-0 opacity-45 dark:opacity-80"
        style={{
          backgroundImage:
            "conic-gradient(from 0deg at 50% 50%, #5750F1 0deg, #0ABEF9 80deg, transparent 140deg, #8155FF 200deg, #5750F1 280deg, transparent 320deg, #5750F1 360deg)",
          filter: "blur(64px)",
        }}
      />

      <div
        ref={orbARef}
        aria-hidden
        className="pointer-events-none absolute -right-24 -top-32 z-0 h-80 w-80 rounded-full bg-[#5750F1]/25 blur-3xl dark:bg-[#5750F1]/55"
      />
      <div
        ref={orbBRef}
        aria-hidden
        className="pointer-events-none absolute -bottom-32 -left-16 z-0 h-72 w-72 rounded-full bg-[#0ABEF9]/20 blur-3xl dark:bg-[#0ABEF9]/45"
      />
      <div
        ref={orbCRef}
        aria-hidden
        className="pointer-events-none absolute left-1/2 top-1/3 z-0 h-56 w-56 -translate-x-1/2 rounded-full bg-[#F23030]/10 blur-3xl dark:bg-[#F23030]/20"
      />

      <div
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 opacity-[0.06] dark:hidden"
        style={{
          backgroundImage:
            "radial-gradient(circle at 1px 1px, rgb(15 23 42) 1px, transparent 0)",
          backgroundSize: "20px 20px",
        }}
      />
      <div
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 hidden opacity-[0.07] dark:block"
        style={{
          backgroundImage:
            "radial-gradient(circle at 1px 1px, white 1px, transparent 0)",
          backgroundSize: "20px 20px",
        }}
      />

      <div
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 rounded-3xl ring-1 ring-inset ring-slate-900/[0.06] dark:ring-white/10"
      />

      <div className="relative z-10 flex flex-col gap-7 md:flex-row md:items-end md:justify-between">
        <div className="flex-1">
          <span
            data-hero-pill
            className="inline-flex items-center gap-2 rounded-full border border-slate-200/90 bg-white/90 px-3.5 py-1.5 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-600 backdrop-blur-xl dark:border-white/15 dark:bg-white/[0.06] dark:text-white/85"
          >
            <span className="relative flex size-1.5">
              <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-70" />
              <span className="relative inline-flex size-1.5 rounded-full bg-emerald-400" />
            </span>
            Live tender intelligence
            <SparkleIcon className="size-3.5 text-slate-500 dark:text-white/80" />
          </span>

          <h1
            ref={titleRef}
            className="relative z-[1] mt-5 max-w-2xl text-3xl font-bold leading-tight md:text-[44px] md:leading-[1.05]"
            aria-label={headline}
          >
            <span
              data-title-inner
              className="relative z-[1] inline-block will-change-transform"
            >
              <span className="bg-gradient-to-r from-slate-900 via-slate-800 to-slate-500 bg-clip-text text-transparent dark:from-white dark:via-white dark:to-white/60">
                {headline}
              </span>
            </span>
            <span
              aria-hidden
              className="pointer-events-none absolute inset-0 z-0 overflow-hidden"
            >
              <span
                ref={shineRef}
                className="absolute inset-y-0 block w-1/3 opacity-0 blur-[10px] [background:linear-gradient(100deg,transparent_0%,rgba(87,80,241,0.35)_50%,transparent_100%)] dark:[background:linear-gradient(100deg,transparent_0%,rgba(255,255,255,0.45)_50%,transparent_100%)]"
              />
            </span>
          </h1>

          <p className="mt-3 max-w-xl text-sm text-slate-600 md:text-base dark:text-white/65">
            {sub}
          </p>

          <div className="mt-7 flex flex-wrap items-center gap-3">
            <HeroPill
              label="Tracking"
              value={total}
              suffix=" tenders"
              loading={isLoading}
              tone="primary"
            />
            <HeroPill
              label="Active"
              value={active}
              loading={isLoading}
              tone="emerald"
            />
            <HeroPill
              label="Closing soon"
              value={closingSoon}
              loading={isLoading}
              tone="amber"
            />
          </div>
        </div>

        <LiveClock />
      </div>
    </div>
  );
}

function HeroPill({
  label,
  value,
  suffix,
  loading,
  tone,
}: {
  label: string;
  value: number;
  suffix?: string;
  loading: boolean;
  tone: "primary" | "emerald" | "amber";
}) {
  const tones: Record<typeof tone, string> = {
    primary:
      "bg-gradient-to-br from-white to-slate-100 text-[#1B1F3A] shadow-[0_8px_24px_-10px_rgba(15,23,42,0.2)] ring-1 ring-slate-900/5 dark:from-white/95 dark:to-white/75 dark:shadow-[0_10px_30px_-12px_rgba(255,255,255,0.45)] dark:ring-0",
    emerald:
      "border border-emerald-200/80 bg-gradient-to-br from-emerald-50 to-emerald-100/50 text-emerald-900 shadow-[0_8px_24px_-10px_rgba(16,185,129,0.25)] dark:from-emerald-400/30 dark:to-emerald-300/5 dark:text-emerald-50 dark:border-emerald-300/30 dark:shadow-[0_10px_30px_-12px_rgba(16,185,129,0.55)]",
    amber:
      "border border-orange-200/80 bg-gradient-to-br from-amber-50 to-orange-50/80 text-amber-950 shadow-[0_8px_24px_-10px_rgba(251,146,60,0.2)] dark:from-orange-400/30 dark:to-amber-300/5 dark:text-orange-50 dark:border-orange-300/30 dark:shadow-[0_10px_30px_-12px_rgba(251,146,60,0.55)]",
  };
  return (
    <div
      data-hero-pill
      className={cn(
        "group relative flex items-center gap-2 overflow-hidden rounded-full px-4 py-2 text-sm font-semibold backdrop-blur-xl transition-transform hover:scale-[1.04]",
        tones[tone],
      )}
    >
      <span className="text-[10px] font-bold uppercase tracking-[0.16em] opacity-70">
        {label}
      </span>
      <span className="tabular-nums">
        {loading ? (
          "—"
        ) : (
          <AnimatedCounter value={value} suffix={suffix ?? ""} />
        )}
      </span>
      <span
        aria-hidden
        className="pointer-events-none absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/30 to-transparent transition-transform duration-700 group-hover:translate-x-full"
      />
    </div>
  );
}
