"use client";

import * as React from "react";
import Link from "next/link";
import { Landmark, PiggyBank, Scale, Wallet } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import { formatAmount } from "@/lib/format/numbers";
import { customerUrl } from "@/lib/tenant";

import { DashboardWidgetBody } from "@/app/customer/_components/dashboard-charts/dashboard-widget-body";
import { ResponsiveDonutChart } from "@/app/customer/_components/dashboard-charts/responsive-donut-chart";
import { WidgetChartLegend } from "@/app/customer/_components/dashboard-charts/widget-chart-legend";
import { DashboardWidgetShell } from "@/app/customer/_components/dashboard-widget-shell";
import { DashboardCardExcludeHint } from "@/app/customer/_components/dashboard-card-exclude-hint";
import { PortfolioScopeWidgetHint } from "@/app/customer/_components/portfolio-scope-widget-hint";
import { LAYOUT_IDS } from "@/app/customer/_lib/dashboard-layout";
import { useAumCalcMode } from "@/app/customer/_lib/use-aum-calc-mode";
import { useDashboardWidgetData } from "@/app/customer/_lib/use-dashboard-widget-data";
import type { WidgetLayoutTier } from "@/app/customer/_lib/use-widget-container-size";
import { getStaticWidgetDefinition } from "@/app/customer/_lib/dashboard-widget-registry-definitions";
import { buildCashBalanceLiquiditySummarySlices } from "@/app/customer/[tenant]/reports/cash-balance-liquidity/_lib/cash-balance-liquidity-chart-data";
import { liquidityTotalForMode } from "@/app/customer/[tenant]/reports/cash-balance-liquidity/_lib/cash-balance-liquidity-totals";
import { fetchCashBalanceLiquidityWidgetClient } from "@/app/customer/[tenant]/reports/cash-balance-liquidity/_lib/cash-balance-liquidity-widget-api";
import type {
  CashBalanceLiquiditySummary,
  CashBalanceLiquidityWidgetData,
  CashBalanceLiquidityWidgetMeta,
} from "@/app/customer/[tenant]/reports/cash-balance-liquidity/_lib/cash-balance-liquidity-widget-types";
import type { AumCalcMode } from "@/app/customer/[tenant]/settings/_lib/aum-mode-api";

const widgetMeta = getStaticWidgetDefinition("cash_balance_liquidity");

type KpiItem = {
  label: string;
  value: number;
  icon: React.ReactNode;
  tone: "sky" | "blue" | "emerald" | "rose";
};

const KPI_TONES = {
  sky: "border-sky-500/20 bg-sky-500/10 text-sky-700 dark:text-sky-300",
  blue: "border-blue-500/20 bg-blue-500/10 text-blue-700 dark:text-blue-300",
  emerald: "border-emerald-500/20 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
  rose: "border-rose-500/20 bg-rose-500/10 text-rose-700 dark:text-rose-300",
} as const;

function LiquidityKpiStrip({
  summary,
  tier,
  mode,
  meta,
}: {
  summary: CashBalanceLiquiditySummary;
  tier: WidgetLayoutTier;
  mode: AumCalcMode;
  meta: CashBalanceLiquidityWidgetMeta;
}) {
  const cashValue = mode === "gross" ? summary.grossCash : summary.cash;
  const items: KpiItem[] = [
    { label: "Cash", value: cashValue, icon: <Wallet className="size-3.5" />, tone: "sky" },
    { label: "Call deposit", value: summary.call, icon: <Landmark className="size-3.5" />, tone: "blue" },
    { label: "Fixed deposit", value: summary.fixed, icon: <PiggyBank className="size-3.5" />, tone: "emerald" },
    { label: "Leverage", value: summary.leverage, icon: <Scale className="size-3.5" />, tone: "rose" },
  ];

  const liquidityLabel = mode === "gross" ? "Gross liquidity" : "Net liquidity";
  const liquidityTotal = liquidityTotalForMode(summary, mode);

  const netHero = (
    <div className="rounded-lg border border-border/50 bg-muted/30 px-3.5 py-2.5">
      <p className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
        {liquidityLabel} · {summary.currency}
      </p>
      <p
        className={cn(
          "mt-0.5 truncate font-bold tabular-nums text-primary",
          tier === "compact" ? "text-lg" : "text-xl",
        )}
      >
        {formatAmount(liquidityTotal)}
      </p>
    </div>
  );

  const excludedHints =
    mode === "gross" && (meta.excludedCash || meta.excludedLeverage) ? (
      <div className="mt-2 flex flex-wrap gap-x-3 gap-y-0.5">
        {meta.excludedCash ? (
          <DashboardCardExcludeHint
            deductionLabel="Cash"
            deductionFormatted={formatAmount(meta.excludedCash)}
          />
        ) : null}
        {meta.excludedLeverage ? (
          <DashboardCardExcludeHint
            deductionLabel="Leverage"
            deductionFormatted={formatAmount(meta.excludedLeverage)}
          />
        ) : null}
      </div>
    ) : null;

  if (tier === "compact") {
    return (
      <div className="space-y-3 p-4">
        {netHero}
        {excludedHints}
      </div>
    );
  }

  return (
    <div className="space-y-3 p-4">
      {netHero}

      <div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
        {items.map((item) => (
          <div
            key={item.label}
            className="flex items-center gap-2.5 rounded-lg border border-border/40 bg-card/60 px-2.5 py-1.5"
          >
            <div className={cn("flex size-7 shrink-0 items-center justify-center rounded-md border", KPI_TONES[item.tone])}>
              {item.icon}
            </div>
            <div className="min-w-0">
              <p className="truncate text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
                {item.label}
              </p>
              <p
                className={cn(
                  "truncate text-sm font-bold tabular-nums leading-tight",
                  item.tone === "sky" && item.value < 0 && "text-rose-600 dark:text-rose-400",
                  item.tone === "blue" && "text-blue-700 dark:text-blue-300",
                  item.tone === "emerald" && "text-emerald-700 dark:text-emerald-300",
                  item.tone === "rose" && "text-rose-700 dark:text-rose-300",
                  item.tone === "sky" && item.value >= 0 && "text-foreground",
                )}
              >
                {formatAmount(item.value)}
              </p>
            </div>
          </div>
        ))}
      </div>
      {excludedHints}
    </div>
  );
}

function chartSizeForTier(tier: WidgetLayoutTier) {
  if (tier === "compact") return { min: 100, max: 140 };
  if (tier === "expanded") return { min: 150, max: 220 };
  return { min: 130, max: 180 };
}

function CompositionPanel({
  slices,
  summary,
  tier,
  mode,
}: {
  slices: ReturnType<typeof buildCashBalanceLiquiditySummarySlices>;
  summary: CashBalanceLiquiditySummary;
  tier: WidgetLayoutTier;
  mode: AumCalcMode;
}) {
  const { min, max } = chartSizeForTier(tier);
  const liquidityLabel = mode === "gross" ? "Gross" : "Net";
  const liquidityTotal = liquidityTotalForMode(summary, mode);

  if (tier === "compact") {
    return (
      <div className="grid min-h-0 flex-1 grid-cols-[minmax(0,1fr)_minmax(0,0.95fr)] items-center gap-3 p-4 pt-0">
        <div className="min-w-0">
          <p className="mb-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
            Composition · {summary.currency}
          </p>
          <WidgetChartLegend items={slices} maxItems={3} />
        </div>
        <div className="flex items-center justify-center">
          <ResponsiveDonutChart slices={slices} minSize={min} maxSize={max} />
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-0 flex-1 p-4 pt-0">
      <div className="mb-3 flex items-center justify-between gap-2">
        <p className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
          Portfolio composition
        </p>
        <span className="text-[10px] tabular-nums text-muted-foreground">Positive components only</span>
      </div>
      <div className="grid items-center gap-4 sm:grid-cols-[minmax(120px,0.85fr)_minmax(0,1.15fr)]">
        <div className="relative mx-auto w-full max-w-[220px]">
          <div className="relative z-10">
            <ResponsiveDonutChart slices={slices} minSize={min} maxSize={max} />
          </div>
          {slices.length > 0 ? (
            <div className="pointer-events-none absolute inset-0 z-0 flex flex-col items-center justify-center px-4 text-center">
              <span className="text-[9px] font-semibold uppercase tracking-wide text-muted-foreground">
                {liquidityLabel}
              </span>
              <span className="text-xs font-bold tabular-nums leading-tight text-primary">
                {formatAmount(liquidityTotal)}
              </span>
              <span className="text-[9px] text-muted-foreground">{summary.currency}</span>
            </div>
          ) : null}
        </div>
        <WidgetChartLegend items={slices} />
      </div>
    </div>
  );
}

function CashBalanceLiquidityBody({
  data,
  mode,
}: {
  data: CashBalanceLiquidityWidgetData;
  mode: AumCalcMode;
}) {
  const summary = data.summary!;
  const summarySlices = React.useMemo(
    () => buildCashBalanceLiquiditySummarySlices(summary, mode),
    [summary, mode],
  );

  return (
    <DashboardWidgetBody className="min-h-0 flex-1">
      {({ tier }) => (
        <>
          <LiquidityKpiStrip summary={summary} tier={tier} mode={mode} meta={data.meta} />
          <CompositionPanel slices={summarySlices} summary={summary} tier={tier} mode={mode} />
        </>
      )}
    </DashboardWidgetBody>
  );
}

export function CashBalanceLiquidityWidget() {
  const { mode } = useAumCalcMode();
  const fetchIndividual = React.useCallback(async (resolvedTenant: string) => {
    const result = await fetchCashBalanceLiquidityWidgetClient(resolvedTenant);
    return { data: result.data, errorMessage: result.errorMessage };
  }, []);

  const { tenant, data, loading, refreshing, error, refresh } = useDashboardWidgetData<CashBalanceLiquidityWidgetData>({
    layoutId: LAYOUT_IDS.cashBalanceLiquidity,
    fetchIndividual,
  });

  const reportHref = customerUrl(tenant, widgetMeta.reportPath ?? "/reports/liquidity-report");

  return (
    <DashboardWidgetShell
      title={widgetMeta.label}
      subtitle={
        data ? (
          <p className="flex min-w-0 items-center gap-1.5 truncate">
            <span className="shrink-0">
              {data.meta.bankCount} banks · {data.meta.currencyCount} currencies · {data.meta.positionCount}{" "}
              positions
            </span>
            <PortfolioScopeWidgetHint inline />
          </p>
        ) : (
          "Cash, deposits, and leverage by currency"
        )
      }
      reportHref={reportHref}
      loading={loading && !data}
      refreshing={refreshing}
      error={error}
      onRefresh={refresh}
      loadingContent={
        <div className="space-y-3 p-4">
          <Skeleton className="h-16 w-full rounded-lg" />
          <div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
            {Array.from({ length: 4 }).map((_, i) => (
              <Skeleton key={i} className="h-12 w-full rounded-lg" />
            ))}
          </div>
          <Skeleton className="h-40 w-full rounded-lg" />
        </div>
      }
      emptyContent={
        <div className="flex min-h-[200px] flex-col items-center justify-center p-4 text-center">
          <p className="text-sm text-muted-foreground">No cash balance liquidity data available.</p>
          <Button asChild variant="link" size="sm" className="mt-1 h-auto p-0">
            <Link href={reportHref}>Open cash details report</Link>
          </Button>
        </div>
      }
    >
      {data && data.summary ? <CashBalanceLiquidityBody data={data} mode={mode} /> : null}
    </DashboardWidgetShell>
  );
}
