"use client";

import * as React from "react";
import { Save } from "lucide-react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { presetForDefaultLayout } from "@/app/customer/_lib/default-layout";
import { useDefaultLayout } from "@/app/customer/_lib/use-default-layout";
import { loadDashboardAssetWidgetSettings, updateDashboardAssetWidgetSettings } from "../../../_lib/dashboard-widgets-api";
import type { DashboardTopHoldingsWidget } from "../../../_lib/dashboard-widgets-server-api";
import type { WidgetConfigPanelProps } from "../types";
import { errorMessageOr, toastApiError } from "@/lib/toast-api-error";
import { dispatchDashboardWidgetConfigSaved } from "@/app/customer/_lib/dashboard-widget-configure-events";

const LAYOUT_OPTIONS = [
  { value: "default", label: "Default (Asset Class)" },
  { value: "macro", label: "Macro" },
  { value: "bridge", label: "Bridge" },
] as const;

type TopHoldingsLayout = (typeof LAYOUT_OPTIONS)[number]["value"];

function resolveLayout(
  widget: DashboardTopHoldingsWidget | null,
  tenantLayout: string,
): TopHoldingsLayout {
  const layout = widget?.layout?.trim().toLowerCase();
  const match = LAYOUT_OPTIONS.find((option) => option.value === layout);
  if (match) return match.value;
  const fromTenant = presetForDefaultLayout(tenantLayout).assetAllocationType;
  return LAYOUT_OPTIONS.find((option) => option.value === fromTenant)?.value ?? "default";
}

export function TopHoldingsConfigPanel({
  tenant,
  widget,
  onClose,
  onWidgetsChanged,
}: WidgetConfigPanelProps) {
  const { layout: tenantLayout, loading: layoutLoading } = useDefaultLayout(tenant);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [busy, setBusy] = React.useState(false);
  const [layout, setLayout] = React.useState<TopHoldingsLayout>("default");
  const [widgetId, setWidgetId] = React.useState<number>(widget?.widget_id ?? 0);

  React.useEffect(() => {
    let cancelled = false;
    void (async () => {
      setLoading(true);
      setError(null);
      try {
        const data = await loadDashboardAssetWidgetSettings(tenant);
        if (cancelled) return;
        const match =
          widget != null
            ? (data.top_holdings_widgets ?? []).find(
                (entry) => Number(entry.widget_id) === Number(widget.widget_id),
              ) ?? null
            : (data.top_holdings_widgets?.[0] ?? null);
        setWidgetId(match?.widget_id ?? widget?.widget_id ?? data.top_holdings_widgets?.[0]?.widget_id ?? 0);
        if (!layoutLoading) {
          setLayout(resolveLayout(match, tenantLayout));
        }
      } catch (loadError) {
        if (!cancelled) {
          setError(errorMessageOr(loadError, "Top Holdings settings could not be loaded."));
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [layoutLoading, tenant, tenantLayout, widget]);

  async function save() {
    if (!(widgetId > 0)) {
      toast.error("A valid Top Holdings widget is required.");
      return;
    }
    setBusy(true);
    try {
      await updateDashboardAssetWidgetSettings(tenant, {
        operation: "top-holdings-save",
        widgetId,
        layout,
      });
      dispatchDashboardWidgetConfigSaved({ widgetId });
      toast.success("Top Holdings widget saved");
      onWidgetsChanged?.();
      onClose();
    } catch (saveError) {
      toastApiError(saveError, "Top Holdings widget could not be saved.");
    } finally {
      setBusy(false);
    }
  }

  if (loading || layoutLoading) {
    return <p className="text-muted-foreground text-sm">Loading configuration…</p>;
  }
  if (error) return <p className="text-destructive text-sm">{error}</p>;

  return (
    <div className="overflow-hidden rounded-lg border bg-card">
      <div className="space-y-2 p-4">
        <Label htmlFor="th-layout">Layout</Label>
        <Select value={layout} onValueChange={(value) => setLayout(value as TopHoldingsLayout)}>
          <SelectTrigger id="th-layout">
            <SelectValue placeholder="Select layout" />
          </SelectTrigger>
          <SelectContent>
            {LAYOUT_OPTIONS.map((option) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <p className="text-muted-foreground text-xs">
          Controls how Top Holdings groups tab categories: Default asset classes, Macro groups, or
          Bridge groups.
        </p>
      </div>

      <div className="flex justify-end border-t p-3">
        <Button type="button" size="sm" className="gap-2" disabled={busy} onClick={() => void save()}>
          <Save className="size-4" />
          {busy ? "Saving…" : "Save Widget"}
        </Button>
      </div>
    </div>
  );
}
