"use client";

import * as React from "react";
import { useParams } from "next/navigation";

import { customerUrl } from "@/lib/tenant";

import { holdingsWidgetLayoutId } from "@/app/customer/_components/holdings-widgets-grid";
import { useWidgetSettingsAction } from "@/app/customer/_components/dashboard-widget-configure-provider";
import { useBatchedWidgetLoader } from "@/app/customer/_lib/use-batched-widget-loader";
import { useDashboardWidgetConfigRefresh } from "@/app/customer/_lib/use-dashboard-widget-config-refresh";
import { configureParamForWidget } from "@/app/customer/[tenant]/settings/_components/widget-config";

import { fetchAssetAllocationWidgetClient } from "@/app/customer/[tenant]/reports/asset-allocation/_lib/asset-allocation-widget-api";
import type { AssetAllocationWidgetData } from "@/app/customer/[tenant]/reports/asset-allocation/_lib/asset-allocation-widget-server-api";

import { HoldingsDonutWidget, type HoldingsDonutSlice } from "./holdings-donut-widget";
import { isHoldingsDrillPending } from "./holdings-widget-utils";

type DrillState = {
  asset?: string;
  chGroup?: string;
};

type AssetAllocationWidgetProps = {
  allocationId: number;
  title?: string;
  className?: string;
  layoutId?: string;
};

export function AssetAllocationWidget({
  allocationId,
  title = "Asset Allocation",
  className,
  layoutId: layoutIdProp,
}: AssetAllocationWidgetProps) {
  const params = useParams<{ tenant: string }>();
  const tenant = params?.tenant ?? "";
  const layoutId = layoutIdProp ?? holdingsWidgetLayoutId("aa", allocationId);

  const [drill, setDrill] = React.useState<DrillState>({});
  const isDrilled = Boolean(drill.asset || drill.chGroup);

  const fetchIndividual = React.useCallback(async () => {
    if (!tenant || allocationId <= 0) {
      return { data: null, errorMessage: null };
    }
    const result = await fetchAssetAllocationWidgetClient(tenant, {
      allocationId,
      asset: drill.asset,
      chGroup: drill.chGroup,
    });
    return { data: result.data, errorMessage: result.errorMessage };
  }, [tenant, allocationId, drill.asset, drill.chGroup]);

  const { data, loading, refreshing, error, refresh } = useBatchedWidgetLoader<AssetAllocationWidgetData>({
    layoutId,
    fetchIndividual,
    skipBatch: isDrilled,
  });

  useDashboardWidgetConfigRefresh(allocationId, refresh);

  const slices: HoldingsDonutSlice[] = React.useMemo(() => {
    if (!data?.classes) return [];
    return data.classes.map((row) => ({
      name: row.name,
      mv: row.mv,
      mv_fmt: row.mv_fmt,
      pct: row.pct,
      color: row.color ?? undefined,
      drillable:
        !isDrilled &&
        !data.drill_active &&
        (Boolean(row.asset_code) ||
          Boolean(row.drill_group) ||
          data.report_mode === "macro_consolidated" ||
          data.report_mode === "bchr_report"),
    }));
  }, [data, isDrilled]);

  const handleDrill = React.useCallback(
    (slice: HoldingsDonutSlice) => {
      if (!data || isDrilled || data.drill_active) return;
      const row = data.classes.find((item) => item.name === slice.name);
      if (!row) return;

      if (data.report_mode === "macro_consolidated" || data.report_mode === "bchr_report") {
        const group = row.drill_group ?? row.name;
        if (!group) return;
        setDrill({ chGroup: group });
        return;
      }

      if (row.asset_code) {
        setDrill({ asset: row.asset_code });
      }
    },
    [data, isDrilled],
  );

  const settingsHrefFallback = customerUrl(
    tenant,
    `/settings?section=dashboard&configure=${configureParamForWidget("aa", allocationId)}`,
  );
  const { settingsHref, onSettingsClick } = useWidgetSettingsAction(allocationId, settingsHrefFallback);
  const reportHref = customerUrl(tenant, "/reports/asset-allocation");
  const drillPending = isHoldingsDrillPending(isDrilled, data?.drill_active);
  const drillHint =
    data && !isDrilled && !data.drill_active
      ? data.report_mode === "macro_consolidated" || data.report_mode === "bchr_report"
        ? "Click: drill into group"
        : "Click: drill into Asset Type"
      : null;

  return (
    <HoldingsDonutWidget
      title={title}
      subtitle="TOTAL MARKET VALUE"
      currency={data?.currency ?? "USD"}
      totalMv={data?.total_mv ?? 0}
      totalMvFmt={data?.total_mv_fmt ?? "0.00"}
      slices={slices}
      loading={loading}
      refreshing={refreshing}
      drillPending={drillPending}
      error={error}
      settingsHref={settingsHref}
      onSettingsClick={onSettingsClick}
      reportHref={reportHref}
      drillHint={drillHint}
      canDrillUp={isDrilled}
      onRefresh={() => void refresh()}
      onDrill={handleDrill}
      onDrillUp={() => setDrill({})}
      className={className}
    />
  );
}
