"use client";

import { cn } from "@/lib/utils";
import gsap from "gsap";
import { useLayoutEffect, useMemo, useRef } from "react";
import { AnimatedCounter } from "./animated-counter";
import {
  ClockIcon,
  CoinIcon,
  PulseIcon,
  TenderIcon,
  TrendUpIcon,
} from "./icons";
import { Sparkline } from "./sparkline";

type Props = {
  total: number;
  active: number;
  closingSoon: number;
  totalValue: number;
  valueCurrency: string;
  trend: { count: number }[];
  isLoading: boolean;
};

const compact = new Intl.NumberFormat("en", {
  notation: "compact",
  compactDisplay: "short",
  maximumFractionDigits: 1,
});

const fmtCompact = (v: number) => compact.format(Math.max(0, v));

export function TenderStatCards({
  total,
  active,
  closingSoon,
  totalValue,
  valueCurrency,
  trend,
  isLoading,
}: Props) {
  const rootRef = useRef<HTMLDivElement>(null);

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

    const ctx = gsap.context(() => {
      if (reduced) return;
      gsap.from("[data-stat-card]", {
        y: 40,
        opacity: 0,
        scale: 0.94,
        duration: 0.75,
        stagger: 0.09,
        ease: "back.out(1.4)",
        delay: 0.1,
      });
    }, rootRef);
    return () => ctx.revert();
  }, []);

  const activePct = total > 0 ? Math.round((active / total) * 100) : 0;
  const closingPct = total > 0 ? Math.round((closingSoon / total) * 100) : 0;

  const series = useMemo(() => {
    const base = trend.map((t) => t.count);
    if (!base.length) return { total: [], active: [], closing: [], value: [] };
    return {
      total: base,
      active: base.map((v) => Math.max(0, Math.round(v * 0.62 + 1))),
      closing: base.map((v, i) =>
        Math.max(0, Math.round(v * 0.2 + (i % 3 === 0 ? 1 : 0))),
      ),
      value: base.map((v) => Math.max(0, Math.round(v * 1.1 + 2))),
    };
  }, [trend]);

  return (
    <div
      ref={rootRef}
      className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4"
    >
      <StatCard
        label="Total Tenders"
        value={total}
        Icon={TenderIcon}
        color="#5750F1"
        accentGradient="from-[#5750F1] to-[#7B6CFF]"
        ringColor="ring-[#5750F1]/30"
        hint="In your watchlist"
        series={series.total}
        loading={isLoading}
      />
      <StatCard
        label="Active Now"
        value={active}
        Icon={PulseIcon}
        color="#22AD5C"
        accentGradient="from-emerald-500 to-emerald-400"
        ringColor="ring-emerald-400/30"
        hint={`${activePct}% of total`}
        delta={activePct}
        series={series.active}
        loading={isLoading}
      />
      <StatCard
        label="Closing Soon"
        value={closingSoon}
        Icon={ClockIcon}
        color="#F59460"
        accentGradient="from-orange-500 to-amber-400"
        ringColor="ring-orange-400/30"
        hint={`${closingPct}% in next 7 days`}
        series={series.closing}
        loading={isLoading}
        urgent={closingSoon > 0}
      />
      <StatCard
        label="Estimated Value"
        value={totalValue}
        formatter={(v) => fmtCompact(v)}
        prefix={currencySymbol(valueCurrency)}
        Icon={CoinIcon}
        color="#0ABEF9"
        accentGradient="from-[#0ABEF9] to-[#3C50E0]"
        ringColor="ring-[#0ABEF9]/30"
        hint={`${valueCurrency} aggregated`}
        series={series.value}
        loading={isLoading}
      />
    </div>
  );
}

function currencySymbol(code: string) {
  switch (code) {
    case "EUR":
      return "€";
    case "USD":
      return "$";
    case "GBP":
      return "£";
    case "AED":
      // Arabic "د.إ" is RTL; mixing it with compact Latin digits + "M" breaks
      // bidi layout (overlap with suffix). Use Latin code — matches hint "AED aggregated".
      return "AED\u00A0";
    default:
      return "";
  }
}

function StatCard({
  label,
  value,
  Icon,
  color,
  accentGradient,
  ringColor,
  hint,
  delta,
  prefix,
  formatter,
  series,
  loading,
  urgent,
}: {
  label: string;
  value: number;
  Icon: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
  color: string;
  accentGradient: string;
  ringColor: string;
  hint: string;
  delta?: number;
  prefix?: string;
  formatter?: (v: number) => string;
  series: number[];
  loading: boolean;
  urgent?: boolean;
}) {
  const cardRef = useRef<HTMLDivElement>(null);
  const spotRef = useRef<HTMLDivElement>(null);
  const borderRef = useRef<HTMLDivElement>(null);

  useLayoutEffect(() => {
    const reduced =
      typeof window !== "undefined" &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduced || !cardRef.current) return;
    const el = cardRef.current;
    const spot = spotRef.current;

    const onMove = (e: MouseEvent) => {
      const r = el.getBoundingClientRect();
      const x = e.clientX - r.left;
      const y = e.clientY - r.top;
      const px = x / r.width - 0.5;
      const py = y / r.height - 0.5;

      gsap.to(el, {
        rotateY: px * 7,
        rotateX: -py * 7,
        transformPerspective: 900,
        duration: 0.4,
        ease: "power2.out",
      });

      if (spot) {
        spot.style.setProperty("--spot-x", `${x}px`);
        spot.style.setProperty("--spot-y", `${y}px`);
      }
      gsap.to(spot, { opacity: 1, duration: 0.25 });
      gsap.to(borderRef.current, { opacity: 1, duration: 0.4 });
    };

    const onLeave = () => {
      gsap.to(el, {
        rotateY: 0,
        rotateX: 0,
        duration: 0.7,
        ease: "power3.out",
      });
      gsap.to(spot, { opacity: 0, duration: 0.5 });
      gsap.to(borderRef.current, { opacity: 0, duration: 0.5 });
    };

    el.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", onLeave);
    return () => {
      el.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", onLeave);
    };
  }, []);

  return (
    <div
      ref={cardRef}
      data-stat-card
      className={cn(
        "group relative isolate min-h-[180px] overflow-hidden rounded-2xl bg-white p-5 shadow-1 ring-1 ring-stroke transition-shadow hover:shadow-2 dark:bg-gray-dark dark:ring-stroke-dark dark:shadow-card",
      )}
      style={{ transformStyle: "preserve-3d" }}
    >
      <div
        ref={borderRef}
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 rounded-2xl opacity-0"
        style={{
          background: `linear-gradient(135deg, ${color}55, transparent 40%, transparent 60%, ${color}55)`,
          WebkitMask:
            "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)",
          WebkitMaskComposite: "xor",
          maskComposite: "exclude",
          padding: "1px",
        }}
      />

      <div
        ref={spotRef}
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 opacity-0 transition-opacity"
        style={{
          background: `radial-gradient(240px circle at var(--spot-x, 50%) var(--spot-y, 50%), ${color}33, transparent 65%)`,
        }}
      />

      <div
        aria-hidden
        className={cn(
          "pointer-events-none absolute -right-12 -top-12 z-0 size-32 rounded-full bg-gradient-to-br opacity-25 blur-2xl transition-opacity duration-500 group-hover:opacity-60",
          accentGradient,
        )}
      />

      <div className="pointer-events-none absolute inset-x-0 bottom-0 z-0 h-20 opacity-90">
        {!loading && series.length > 0 && (
          <Sparkline
            series={series}
            color={color}
            className="h-full w-full"
            delay={0.6}
          />
        )}
      </div>

      <div className="relative z-10 flex items-start justify-between">
        <div
          className={cn(
            "inline-flex size-12 items-center justify-center rounded-xl bg-gradient-to-br text-white shadow-lg ring-4",
            accentGradient,
            ringColor,
          )}
          style={{
            boxShadow: `0 10px 30px -10px ${color}88`,
          }}
        >
          <Icon className="size-6" />
        </div>
        {urgent && (
          <span className="inline-flex items-center gap-1 rounded-full bg-orange-light/10 px-2 py-0.5 text-[11px] font-medium text-orange-light">
            <span className="relative flex size-1.5">
              <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-orange-light opacity-75" />
              <span className="relative inline-flex size-1.5 rounded-full bg-orange-light" />
            </span>
            Action needed
          </span>
        )}
        {delta !== undefined && !urgent && (
          <span className="inline-flex items-center gap-1 rounded-full bg-green-light-7 px-2 py-0.5 text-[11px] font-medium text-green dark:bg-green/15 dark:text-green-light-3">
            <TrendUpIcon className="size-3" />
            {delta}%
          </span>
        )}
      </div>

      <div className="relative z-10 mt-5">
        <div
          className="text-[30px] font-bold leading-none"
          dir="ltr"
          lang="en"
        >
          {loading ? (
            <span className="inline-block h-8 w-24 animate-pulse rounded bg-gray-2 dark:bg-dark-3" />
          ) : (
            <span
              className={cn(
                "inline-block bg-gradient-to-br bg-clip-text text-transparent",
                accentGradient,
              )}
            >
              <AnimatedCounter
                value={value}
                prefix={prefix ?? ""}
                formatter={formatter}
              />
            </span>
          )}
        </div>
        <div className="mt-2 text-sm font-semibold text-dark dark:text-white">
          {label}
        </div>
        <div className="mt-1 text-xs text-dark-6 dark:text-dark-6">{hint}</div>
      </div>
    </div>
  );
}
