"use client";

import * as React from "react";
import {
  BarChart3,
  Bitcoin,
  Boxes,
  Building2,
  CircleDollarSign,
  Coins,
  HandCoins,
  Hexagon,
  Landmark,
  Layers,
  LineChart,
  MinusCircle,
  PieChart,
  PiggyBank,
  Scale,
  UserRound,
  Users,
  Wallet,
} from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";

import type { DashboardAssetCard } from "@/app/customer/[tenant]/dashboard/_lib/dashboard-server-api";
import type { AumCalcMode } from "@/app/customer/[tenant]/settings/_lib/aum-mode-api";
import { DashboardCardExcludeHint } from "@/app/customer/_components/dashboard-card-exclude-hint";
import type { CustomerGridColumn } from "@/app/customer/_lib/customer-grid-columns";
import {
  isStaticWidgetLayoutId,
} from "@/app/customer/_lib/dashboard-widget-registry-definitions";

export const ASSET_ORDER = [
  "total",
  "stock",
  "stockFunds",
  "mixedFund",
  "bond",
  "bondFund",
  "commodity",
  "otherAsset",
  "crypto",
  "fixedDeposit",
  "callDeposit",
  "cash",
  "od",
  "leverage",
  "structure",
  "accumulatorValue",
  "decumulatorValue",
] as const;

export const ASSET_ICONS: Record<string, React.ComponentType<{ className?: string }>> = {
  total: CircleDollarSign,
  stock: LineChart,
  stockFunds: BarChart3,
  mixedFund: PieChart,
  bond: Landmark,
  bondFund: Layers,
  commodity: Hexagon,
  otherAsset: Boxes,
  crypto: Bitcoin,
  fixedDeposit: PiggyBank,
  callDeposit: HandCoins,
  cash: Wallet,
  od: MinusCircle,
  leverage: Scale,
  structure: Building2,
  accumulatorValue: Coins,
  decumulatorValue: Coins,
  accumulator: Coins,
  options: Layers,
  users: Users,
  customers: UserRound,
  userGroups: Building2,
};

export const DEFAULT_CORPORATE_CATALOG: CustomerGridColumn[] = [
  { key: "users", label: "Total Users", group: "cards" },
  { key: "customers", label: "Total Customers", group: "cards" },
  { key: "userGroups", label: "Total User Groups", group: "cards" },
  { key: "total", label: "Total Value", group: "cards" },
  { key: "stock", label: "Stock", group: "cards" },
  { key: "stockFunds", label: "Stock Funds", group: "cards" },
  { key: "mixedFund", label: "Mixed Fund", group: "cards" },
  { key: "bond", label: "Bond", group: "cards" },
  { key: "bondFund", label: "Bond Fund", group: "cards" },
  { key: "commodity", label: "Commodity", group: "cards" },
  { key: "otherAsset", label: "Other Asset", group: "cards" },
  { key: "crypto", label: "Crypto", group: "cards" },
  { key: "fixedDeposit", label: "Fixed Deposit", group: "cards" },
  { key: "callDeposit", label: "Call Deposit", group: "cards" },
  { key: "cash", label: "Cash", group: "cards" },
  { key: "od", label: "Overdraft", group: "cards" },
  { key: "leverage", label: "Leverage", group: "cards" },
  { key: "structure", label: "Structure", group: "cards" },
  { key: "accumulatorValue", label: "Accumulator (Value)", group: "cards" },
  { key: "decumulatorValue", label: "Decumulator (Value)", group: "cards" },
  { key: "accumulator", label: "Accumulator", group: "cards" },
  { key: "options", label: "Options", group: "cards" },
];

/** Org count cards that belong in the customize grid (permission-gated). */
export const CORPORATE_COUNT_CARD_KEYS = ["users", "customers", "userGroups"] as const;

export const DASHBOARD_FIELD_GROUPS = [
  { id: "cards", label: "Cards" },
  { id: "widgets", label: "Widgets (from Settings)" },
] as const;

export function isStaticWidgetKey(key: string): boolean {
  return isStaticWidgetLayoutId(key);
}

const GRID_CARD_CLASS =
  "h-full gap-0 border-0 bg-transparent py-0 shadow-none";

function formatAssetSharePercent(amount: number, totalAmount: number): string | null {
  if (!Number.isFinite(amount) || !Number.isFinite(totalAmount) || totalAmount === 0) {
    return null;
  }
  return `${((amount / totalAmount) * 100).toFixed(2)}%`;
}

function CardAumModeToggle({
  mode,
  onModeChange,
}: {
  mode: AumCalcMode;
  onModeChange: (mode: AumCalcMode) => void;
}) {
  return (
    <div
      className="inline-flex w-fit shrink-0 gap-0.5 rounded-md border border-border/60 bg-muted/40 p-0.5"
      role="group"
      aria-label="Gross or net amount"
      onClick={(event) => event.stopPropagation()}
    >
      {(["gross", "net"] as const).map((value) => (
        <button
          key={value}
          type="button"
          className={cn(
            "rounded px-1.5 py-0.5 text-[9px] font-semibold capitalize transition-colors",
            mode === value
              ? "bg-background text-foreground shadow-sm"
              : "text-muted-foreground hover:text-foreground",
          )}
          aria-pressed={mode === value}
          onClick={() => onModeChange(value)}
        >
          {value}
        </button>
      ))}
    </div>
  );
}

function CardPercentBadge({
  label,
  percent,
  compact = false,
}: {
  label: string;
  percent: string;
  compact?: boolean;
}) {
  return (
    <span
      className={cn(
        "shrink-0 whitespace-nowrap rounded-full border border-border/60 bg-muted/70 font-semibold tabular-nums text-foreground/80 dark:bg-sky-950/40 dark:text-sky-100/90",
        compact ? "px-1.5 py-0.5 text-[10px]" : "px-2 py-0.5 text-xs",
      )}
      title={`${label} share of Total Value`}
    >
      {percent}
    </span>
  );
}

function CardRightRail({
  cardLabel,
  percentLabel,
  compact = false,
}: {
  cardLabel: string;
  percentLabel: string | null;
  compact?: boolean;
}) {
  if (!percentLabel) return null;

  return <CardPercentBadge label={cardLabel} percent={percentLabel} compact={compact} />;
}

export function AssetCardView({
  card,
  hero = false,
  totalAmount,
  nested = false,
  displayAmount,
  displayFormatted,
  showGrossDeduction,
  aumMode,
  onAumModeChange,
}: {
  card: DashboardAssetCard;
  hero?: boolean;
  /** Total Value amount used to compute share % on small cards only. */
  totalAmount?: number;
  /** Clubbed-section member: stack content so full amounts fit. */
  nested?: boolean;
  displayAmount?: number;
  displayFormatted?: string;
  showGrossDeduction?: boolean;
  aumMode?: AumCalcMode;
  onAumModeChange?: (mode: AumCalcMode) => void;
}) {
  const Icon = ASSET_ICONS[card.key] ?? CircleDollarSign;
  const amount = displayAmount ?? card.amount;
  const display = displayFormatted ?? card.display;
  const negative = amount < 0;
  const deductionFormatted =
    showGrossDeduction === false ? null : card.grossDeductionFormatted;
  const hasExcludeNote =
    (card.excludeCount ?? 0) > 0 || Boolean(deductionFormatted);
  const deductionLabel =
    card.key === "cash" ? "Cash" : card.key === "leverage" ? "Leverage" : null;
  const percentLabel =
    !hero && totalAmount != null
      ? formatAssetSharePercent(amount, totalAmount)
      : null;
  const showAumToggle = onAumModeChange != null && aumMode != null;

  return (
    <Card
      className={cn(
        "h-full gap-0 border-0 bg-transparent py-0 shadow-none",
        hero && "border-primary/25 bg-muted/30",
        !hero && GRID_CARD_CLASS,
      )}
    >
      <CardContent
        className={cn(
          "flex h-full px-2.5",
          hero
            ? "items-center gap-2 py-2 sm:px-3"
            : nested
              ? "items-stretch py-1.5"
              : "items-center gap-2.5 py-1.5",
          showAumToggle && !hero && "relative",
        )}
      >
        {showAumToggle && aumMode && onAumModeChange ? (
          <div
            className={cn(
              "absolute right-2.5 z-10",
              nested ? "top-0" : "top-1.5",
            )}
          >
            <CardAumModeToggle mode={aumMode} onModeChange={onAumModeChange} />
          </div>
        ) : null}
        {hero ? (
          <>
            <div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground">
              <Icon className="size-3.5" />
            </div>
            <div className="min-w-0 flex-1 leading-tight">
              <p
                className={cn(
                  "truncate font-semibold text-sm tabular-nums tracking-tight sm:text-base",
                  negative ? "text-red-600 dark:text-red-400" : "text-foreground",
                )}
              >
                {display}
              </p>
              <DashboardCardExcludeHint
                excludeCount={card.excludeCount}
                deductionLabel={deductionLabel}
                deductionFormatted={deductionFormatted}
                className={hasExcludeNote ? "mt-px" : undefined}
              />
              <p
                className={cn(
                  "truncate font-medium text-[11px] text-primary/90",
                  hasExcludeNote ? "mt-0.5" : "mt-1",
                )}
              >
                {card.label}
              </p>
            </div>
          </>
        ) : nested ? (
          <div className="flex min-w-0 flex-1 flex-col justify-center gap-0.5 leading-tight">
            <div
              className={cn(
                "flex min-w-0 items-center gap-1.5",
                showAumToggle && "pr-[4.25rem]",
              )}
            >
              <div className="flex size-6 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground">
                <Icon className="size-3" />
              </div>
              <p className="min-w-0 flex-1 text-[10px] font-medium text-muted-foreground [overflow-wrap:anywhere]">
                {card.label}
              </p>
              <CardRightRail cardLabel={card.label} percentLabel={percentLabel} compact />
            </div>
            <p
              className={cn(
                "font-semibold text-xs tabular-nums tracking-tight [overflow-wrap:anywhere] sm:text-[13px]",
                negative ? "text-red-600 dark:text-red-400" : "text-foreground",
              )}
            >
              {display}
            </p>
            <DashboardCardExcludeHint
              excludeCount={card.excludeCount}
              deductionLabel={deductionLabel}
              deductionFormatted={deductionFormatted}
              className={hasExcludeNote ? "mt-px" : undefined}
            />
          </div>
        ) : (
          <>
            <div className="flex min-w-0 flex-1 items-center gap-2">
              <div className="flex size-6 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground">
                <Icon className="size-3" />
              </div>
              <div className="min-w-0 flex-1 leading-tight">
                <p className="truncate text-[10px] font-medium text-muted-foreground">{card.label}</p>
                <p
                  className={cn(
                    "truncate font-semibold text-xs tabular-nums tracking-tight sm:text-[13px]",
                    negative ? "text-red-600 dark:text-red-400" : "text-foreground",
                  )}
                >
                  {display}
                </p>
                <DashboardCardExcludeHint
                  excludeCount={card.excludeCount}
                  deductionLabel={deductionLabel}
                  deductionFormatted={deductionFormatted}
                  className={hasExcludeNote ? "mt-px" : undefined}
                />
              </div>
            </div>
            <CardRightRail cardLabel={card.label} percentLabel={percentLabel} />
          </>
        )}
      </CardContent>
    </Card>
  );
}

export function CountMetricCard({
  title,
  value,
  icon: Icon,
}: {
  title: string;
  value: number;
  icon: React.ComponentType<{ className?: string }>;
}) {
  return (
    <Card className={GRID_CARD_CLASS}>
      <CardContent className="flex h-full items-center gap-2 px-2.5 py-1.5">
        <div className="flex size-6 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground">
          <Icon className="size-3" />
        </div>
        <div className="min-w-0 flex-1 leading-tight">
          <p className="truncate text-xs font-semibold tabular-nums sm:text-[13px]">{value}</p>
          <p className="mt-1 truncate text-[10px] font-medium text-primary/90">{title}</p>
        </div>
      </CardContent>
    </Card>
  );
}

export function DashboardSkeleton() {
  return (
    <div className="flex flex-col gap-2">
      <Skeleton className="h-12 rounded-xl" />
      <div className="grid grid-cols-2 gap-1.5 sm:grid-cols-3 xl:grid-cols-5">
        {Array.from({ length: 10 }).map((_, i) => (
          <Skeleton key={i} className="h-12 rounded-xl" />
        ))}
      </div>
    </div>
  );
}

export function DashboardPageHeader({
  formattedDate,
  actions,
}: {
  formattedDate: string;
  actions?: React.ReactNode;
}) {
  return (
    <div className="flex min-w-0 items-center justify-between gap-3">
      <div className="flex min-w-0 flex-wrap items-baseline gap-x-3 gap-y-0.5">
        <h1 className="text-3xl tracking-tight">Dashboard</h1>
        <p className="truncate text-sm text-muted-foreground">{formattedDate}</p>
      </div>
      {actions ? <div className="flex shrink-0 items-center gap-2">{actions}</div> : null}
    </div>
  );
}
