"use client";

import type { StatMetric } from "@/lib/dashboard/mock-data";
import {
  formatOwnerNumber,
  formatOwnerRupiah,
} from "@/lib/dashboard/owner-dashboard";
import { useCountUp } from "@/lib/hooks/use-count-up";
import { motion } from "motion/react";
import { MaterialIcon } from "../icons/nav-icons";
import { IconTrendDown, IconTrendUp } from "./dashboard-icons";

const accentStyles = [
  "text-primary-500",
  "text-secondary-500",
  "text-success-600",
  "text-primary-700",
] as const;

const STAT_ICONS = [
  "payments",
  "receipt_long",
  "monitoring",
  "table_restaurant",
] as const;

export const STAT_CARD_COUNT = STAT_ICONS.length;

const STAT_LABELS = [
  "Total Penjualan",
  "Jumlah Pesanan",
  "Rata-rata Transaksi",
  "Meja Aktif",
] as const;

type StatCardProps = {
  metric: StatMetric;
  index: number;
};

function formatAnimatedValue(metric: StatMetric, animatedValue: number) {
  if (metric.valueFormat === "rupiah") {
    return formatOwnerRupiah(animatedValue);
  }

  if (metric.valueFormat === "ratio") {
    return `${formatOwnerNumber(animatedValue)} / ${formatOwnerNumber(metric.ratioTotal ?? 0)}`;
  }

  if (metric.valueFormat === "number") {
    return formatOwnerNumber(animatedValue);
  }

  return metric.value;
}

function AnimatedStatValue({ metric }: { metric: StatMetric }) {
  const target = metric.rawValue ?? 0;
  const animatedValue = useCountUp(target, {
    duration: 1,
    decimals: metric.valueFormat === "rupiah" ? 0 : 0,
  });

  if (metric.rawValue == null) {
    return <>{metric.value}</>;
  }

  return <>{formatAnimatedValue(metric, animatedValue)}</>;
}

export function StatCard({ metric, index }: StatCardProps) {
  const change = metric.change;
  const showChangeBadge = change != null;
  const isUp = change != null && change > 0;
  const isDown = change != null && change < 0;
  const iconName = STAT_ICONS[index % STAT_ICONS.length];
  const accentClass = accentStyles[index % accentStyles.length];

  return (
    <motion.article
      initial={{ opacity: 0, y: 16 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{
        duration: 0.45,
        delay: index * 0.08,
        ease: [0.16, 1, 0.3, 1],
      }}
      className="relative flex min-w-0 overflow-hidden rounded-lg border border-neutral-40 bg-neutral-10 p-5"
    >
      <motion.div
        initial={{ opacity: 0, scale: 0.85 }}
        animate={{ opacity: 0.12, scale: 1 }}
        transition={{ duration: 0.6, delay: 0.15 + index * 0.08 }}
        className={`pointer-events-none absolute -right-3 -bottom-3 ${accentClass}`}
        aria-hidden
      >
        <MaterialIcon name={iconName} size={96} />
      </motion.div>

      <div className="relative flex min-w-0 flex-1 flex-col gap-4">
        <div className="flex items-start justify-between gap-3">
          <p className="text-s-regular text-neutral-80">{metric.label}</p>
          {showChangeBadge && (
            <motion.div
              initial={{ opacity: 0, scale: 0.9 }}
              animate={{ opacity: 1, scale: 1 }}
              transition={{ duration: 0.35, delay: 0.25 + index * 0.08 }}
              className={`text-s-medium flex items-center gap-1 rounded-full px-2 py-1 ${
                isUp
                  ? "bg-success-50 text-success-700"
                  : isDown
                    ? "bg-danger-50 text-danger-700"
                    : "bg-neutral-20 text-neutral-80"
              }`}
            >
              {isUp && <IconTrendUp className="size-3.5" />}
              {isDown && <IconTrendDown className="size-3.5" />}
              <span>
                {isUp ? "+" : ""}
                {change}%
              </span>
            </motion.div>
          )}
        </div>

        <div className="flex flex-col gap-1">
          <p className="heading-s tabular-nums text-neutral-100">
            <AnimatedStatValue metric={metric} />
          </p>
          <p className="text-s-regular text-neutral-70">{metric.changeLabel}</p>
        </div>
      </div>
    </motion.article>
  );
}

export function StatCardSkeleton({ index }: { index: number }) {
  const iconName = STAT_ICONS[index % STAT_ICONS.length];
  const label = STAT_LABELS[index % STAT_LABELS.length];
  const accentClass = accentStyles[index % accentStyles.length];

  return (
    <article className="relative flex min-w-0 overflow-hidden rounded-lg border border-neutral-40 bg-neutral-10 p-5">
      <div
        className={`pointer-events-none absolute -right-3 -bottom-3 opacity-[0.12] ${accentClass}`}
        aria-hidden
      >
        <MaterialIcon name={iconName} size={96} />
      </div>

      <div className="relative flex min-w-0 flex-1 flex-col gap-4">
        <div className="flex items-start justify-between gap-3">
          <p className="text-s-regular text-neutral-80">{label}</p>
          <div className="h-6 w-14 animate-pulse rounded-full bg-neutral-20" />
        </div>

        <div className="flex flex-col gap-2">
          <div className="h-7 w-28 animate-pulse rounded bg-neutral-20" />
          <div className="h-4 w-20 animate-pulse rounded bg-neutral-20" />
        </div>
      </div>
    </article>
  );
}
