"use client";

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

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

import { fetchConsolidatedHoldingsWidgetClient } from "@/app/customer/[tenant]/reports/consolidated-holdings-report/_lib/consolidated-holdings-widget-api";
import type { ConsolidatedHoldingsWidgetData } from "@/app/customer/[tenant]/reports/consolidated-holdings-report/_lib/consolidated-holdings-widget-server-api";
import { modeFromWidgetReportMode } from "@/app/customer/[tenant]/reports/consolidated-holdings-report/_lib/consolidated-report-modes";
import { configureParamForWidget } from "@/app/customer/[tenant]/settings/_components/widget-config";
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 { holdingsWidgetLayoutId } from "@/app/customer/_components/holdings-widgets-grid";

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

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

type ConsolidatedHoldingsWidgetProps = {
  widgetId: number;
  title?: string;
  className?: string;
  layoutId?: string;
};

function reportHrefForMode(tenant: string, reportMode: string | undefined) {
  const mode = modeFromWidgetReportMode(reportMode);
  const base = customerUrl(tenant, "/reports/consolidated-holdings-report");
  return mode === "default" ? base : `${base}?mode=${mode}`;
}

export function ConsolidatedHoldingsWidget({
  widgetId,
  title = "Consolidated Holding",
  className,
  layoutId: layoutIdProp,
}: ConsolidatedHoldingsWidgetProps) {
  const params = useParams<{ tenant: string }>();
  const tenant = params?.tenant ?? "";
  const layoutId = layoutIdProp ?? holdingsWidgetLayoutId("ch", widgetId);

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

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

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

  useDashboardWidgetConfigRefresh(widgetId, 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,
      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("ch", widgetId)}`,
  );
  const { settingsHref, onSettingsClick } = useWidgetSettingsAction(widgetId, settingsHrefFallback);
  const reportHref = reportHrefForMode(tenant, data?.report_mode);
  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}
    />
  );
}
