"use client";

import { trpc } from "~/lib/trpc/client.js";
import type { WidgetProps } from "~/components/dashboard/widget-registry.js";
import { formatMoney } from "~/lib/format.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { AnimatedNumber } from "~/components/ui/AnimatedNumber.js";
import { ProgressRing } from "~/components/ui/ProgressRing.js";
import { FadeIn } from "~/components/ui/FadeIn.js";

const ACCENT_COLORS = {
  green: "var(--color-green-500, #22c55e)",
  amber: "var(--color-amber-500, #f59e0b)",
  red: "var(--color-red-500, #ef4444)",
} as const;

function StatCard({
  label,
  value,
  suffix,
  sub,
  details,
  showDetails = false,
  info,
  accentColor,
  delay = 0,
  ring,
}: {
  label: string;
  value: number;
  suffix?: string;
  sub?: string;
  details?: string[];
  showDetails?: boolean;
  info?: React.ReactNode;
  accentColor?: "green" | "amber" | "red";
  delay?: number;
  ring?: { value: number; color: string };
}) {
  const accentBorder = accentColor === "red"
    ? "border-l-red-500"
    : accentColor === "amber"
      ? "border-l-amber-500"
      : accentColor === "green"
        ? "border-l-green-500"
        : "";

  return (
    <FadeIn delay={delay} direction="up">
      <div
        className={`rounded-2xl border border-gray-200 bg-white/80 p-4 shadow-sm dark:border-gray-700 dark:bg-gray-900/70 hover-lift cursor-default ${
          accentColor ? `border-l-[3px] ${accentBorder}` : ""
        }`}
      >
        <span className="flex items-center text-xs font-semibold uppercase tracking-[0.18em] text-gray-500">
          {label}
          {info && <InfoTooltip content={info} />}
        </span>
        {ring ? (
          <div className="mt-2 flex items-center gap-3">
            <ProgressRing value={ring.value} size={56} strokeWidth={4} color={ring.color}>
              <AnimatedNumber value={value} suffix={suffix} className="text-lg font-semibold text-gray-900 dark:text-gray-50" />
            </ProgressRing>
          </div>
        ) : (
          <div className="mt-2">
            <span className="text-2xl font-semibold text-gray-900 dark:text-gray-50">
              <AnimatedNumber value={value} suffix={suffix} />
            </span>
          </div>
        )}
        {sub && <p className="mt-0.5 text-xs text-gray-400 dark:text-gray-500">{sub}</p>}
        {showDetails && details && details.length > 0 ? (
          <div className="mt-2 space-y-1 text-[11px] leading-4 text-gray-500 dark:text-gray-400">
            {details.map((detail) => (
              <p key={detail}>{detail}</p>
            ))}
          </div>
        ) : null}
      </div>
    </FadeIn>
  );
}

function formatShortDate(value?: string | Date | null): string {
  if (!value) {
    return "n/a";
  }

  const date = value instanceof Date ? value : new Date(value);
  if (Number.isNaN(date.getTime())) {
    return "n/a";
  }

  return new Intl.DateTimeFormat("de-DE", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
  }).format(date);
}

export function StatCardsWidget(props: Partial<WidgetProps> = {}) {
  const showDetails = props.config?.showDetails === true;
  const { data, isLoading } = trpc.dashboard.getOverview.useQuery(undefined, {
    staleTime: 60_000,
    placeholderData: (prev) => prev,
  });

  if (isLoading || !data) {
    return (
      <div className="grid grid-cols-2 gap-3 h-full">
        {[...Array(4)].map((_, i) => (
          <div
            key={i}
            className="rounded-2xl border border-gray-200 bg-gray-100 p-4 dark:border-gray-700 dark:bg-gray-800"
          >
            <div className="h-3 w-20 shimmer-skeleton rounded" />
            <div className="h-7 w-16 bg-gray-300 dark:bg-gray-600 rounded" />
            <div className="h-2 w-24 shimmer-skeleton rounded" />
          </div>
        ))}
      </div>
    );
  }

  const budgetPct = data.budgetSummary.avgUtilizationPercent;
  const budgetAccent: "red" | "amber" | "green" =
    budgetPct > 90 ? "red" : budgetPct >= 70 ? "amber" : "green";

  return (
    <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 h-full content-start">
      <StatCard
        label="Total Resources"
        value={data.totalResources}
        sub={`${data.activeResources} active / ${data.inactiveResources ?? Math.max(data.totalResources - data.activeResources, 0)} inactive`}
        details={[
          "Basis: all resource master records",
        ]}
        showDetails={showDetails}
        info="All resources in the system. Sub-line shows active versus inactive records."
        delay={0}
      />
      <StatCard
        label="Active Projects"
        value={data.activeProjects}
        sub={`${data.totalProjects} total / ${data.inactiveProjects ?? Math.max(data.totalProjects - data.activeProjects, 0)} non-active`}
        details={[
          "Basis: project status on the dashboard snapshot",
        ]}
        showDetails={showDetails}
        info="Projects with status ACTIVE. Total includes all statuses (DRAFT, ON_HOLD, COMPLETED, CANCELLED)."
        delay={0.05}
      />
      <StatCard
        label="Total Allocations"
        value={data.totalAllocations}
        sub={`${data.activeAllocations} not cancelled / ${data.cancelledAllocations ?? Math.max(data.totalAllocations - data.activeAllocations, 0)} cancelled`}
        details={[
          "Basis: split allocation read model across explicit and legacy rows",
        ]}
        showDetails={showDetails}
        info="All allocation records ever created. 'Not cancelled' excludes allocations with status CANCELLED."
        delay={0.1}
      />
      <StatCard
        label="Budget Utilization"
        value={budgetPct}
        suffix="%"
        sub={`${formatMoney(data.budgetSummary.totalCostCents)} of ${formatMoney(data.budgetSummary.totalBudgetCents)}`}
        details={[
          `Remaining: ${formatMoney(data.budgetBasis?.remainingBudgetCents ?? (data.budgetSummary.totalBudgetCents - data.budgetSummary.totalCostCents))}`,
          `Basis: ${data.budgetBasis?.trackedAssignmentCount ?? 0} non-cancelled assignments across ${data.budgetBasis?.budgetedProjects ?? 0} budgeted projects`,
          `Window: ${formatShortDate(data.budgetBasis?.windowStart)} - ${formatShortDate(data.budgetBasis?.windowEnd)}`,
        ]}
        showDetails={showDetails}
        info="Sum of costs across non-cancelled allocations divided by total project budgets. Cost uses the effective allocation cost basis including holiday-adjusted working capacity where available."
        accentColor={budgetAccent}
        delay={0.15}
        ring={{ value: budgetPct, color: ACCENT_COLORS[budgetAccent] }}
      />
    </div>
  );
}
