"use client";

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

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

import { CashflowFiltersForm } from "@/app/customer/[tenant]/reports/cashflow/_components/cashflow-report/cashflow-filters-form";
import {
  catalogOptionValues,
  queryAssetClassCodes,
} from "@/app/customer/[tenant]/reports/_shared/lib/asset-class-filter-catalog";
import { useAssetClassFilterCatalog } from "@/app/customer/[tenant]/reports/_shared/lib/use-asset-class-filter-catalog";
import { useDefaultLayout } from "@/app/customer/_lib/use-default-layout";
import {
  buildDefaultCashflowFilters,
  cashflowServerFilterIds,
  DEFAULT_STRUCTURE_STATUS_IDS,
  type CashflowFilters,
  type StructureStatusId,
} from "@/app/customer/[tenant]/reports/cashflow/_components/cashflow-report/schema";
import { defaultCashflowEventTypes } from "@/app/customer/[tenant]/reports/cashflow/_lib/cashflow-event-type-filters";
import { defaultCashflowWidgetDateRange } from "@/app/customer/[tenant]/reports/cashflow/_lib/cashflow-widget-date-range";
import {
  loadDashboardAssetWidgetSettings,
  updateDashboardAssetWidgetSettings,
} from "../../../_lib/dashboard-widgets-api";
import type { DashboardCashflowWidget } from "../../../_lib/dashboard-widgets-server-api";
import type { WidgetConfigPanelProps } from "../types";
import { errorMessageOr, toastApiError } from "@/lib/toast-api-error";

function toFilters(
  widget: DashboardCashflowWidget | null,
  bankIds: string[],
  assetCodes: string[],
): CashflowFilters {
  if (!widget) {
    return buildDefaultCashflowFilters({ bankIds, assetClasses: assetCodes });
  }
  return {
    bankIds: widget.selected_bank_ids.length > 0 ? [...widget.selected_bank_ids] : [...bankIds],
    assetClasses: widget.selected_asset_ids.length > 0 ? [...widget.selected_asset_ids] : [...assetCodes],
    search: "",
    eventTypes: {
      ...defaultCashflowEventTypes,
      ...(widget.event_types ?? {}),
    },
    structureStatusIds:
      widget.structure_status_ids.length > 0
        ? ([...widget.structure_status_ids] as StructureStatusId[])
        : ([...DEFAULT_STRUCTURE_STATUS_IDS] as StructureStatusId[]),
  };
}

export function CashflowCalendarConfigPanel({
  tenant,
  widget,
  mode = "edit",
  onClose,
  onWidgetsChanged,
}: WidgetConfigPanelProps) {
  const isCreate = mode === "create" || !widget;
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [busy, setBusy] = React.useState(false);
  const [title, setTitle] = React.useState("");
  const [filters, setFilters] = React.useState<CashflowFilters | null>(null);
  const [bankOptions, setBankOptions] = React.useState<{ id: string; name: string }[]>([]);
  const [assetClassOptions, setAssetClassOptions] = React.useState<Record<string, string>>({});
  const [currentWidgetId, setCurrentWidgetId] = 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 banks = data.banks.map((bank) => ({ id: bank.bank_id, name: bank.bank_name }));
        const bankIds = banks.map((bank) => bank.id);
        const assetOptions = data.cashflow_asset_class ?? {};
        const assetCodes = Object.keys(assetOptions);
        const match =
          !isCreate && widget
            ? (data.cashflow_widgets ?? []).find(
                (entry) => Number(entry.widget_id) === Number(widget.widget_id),
              ) ?? null
            : null;
        setBankOptions(banks);
        setAssetClassOptions(assetOptions);
        setCurrentWidgetId(match?.widget_id ?? widget?.widget_id ?? 0);
        setTitle(match?.title?.trim() || match?.name || widget?.name || "");
        setFilters(toFilters(match, bankIds, assetCodes));
      } catch (loadError) {
        if (!cancelled) {
          setError(errorMessageOr(loadError, "Cashflow settings could not be loaded."));
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [isCreate, tenant, widget]);

  const bankIds = bankOptions.map((bank) => bank.id);
  const assetCodes = Object.keys(assetClassOptions);
  const { layout, loading: layoutLoading } = useDefaultLayout(tenant);
  const fallbackAssetLabels = React.useMemo(() => Object.values(assetClassOptions), [assetClassOptions]);
  const { catalog: assetClassCatalog } = useAssetClassFilterCatalog(layout, fallbackAssetLabels, {
    enabled: !layoutLoading,
  });
  const assetClassFilterValues = React.useMemo(() => {
    const values = catalogOptionValues(assetClassCatalog);
    return values.length > 0 ? values : assetCodes;
  }, [assetClassCatalog, assetCodes]);

  if (loading) return <p className="text-muted-foreground text-sm">Loading configuration…</p>;
  if (error || !filters) {
    return <p className="text-destructive text-sm">{error ?? "Widget settings are unavailable."}</p>;
  }

  async function save(operation: "cashflow-create" | "cashflow-save") {
    setBusy(true);
    try {
      const selectedBankIds = cashflowServerFilterIds(filters!.bankIds, bankIds);
      const selectedAssetFilterIds = cashflowServerFilterIds(filters!.assetClasses, assetClassFilterValues);
      const selectedAssetIds =
        selectedAssetFilterIds.length === 0
          ? []
          : queryAssetClassCodes(assetClassCatalog, selectedAssetFilterIds);
      // Window is fixed: current month + next (auto-advances). Persist defaults so old custom ranges clear.
      const range = defaultCashflowWidgetDateRange();
      await updateDashboardAssetWidgetSettings(tenant, {
        operation,
        widgetId: operation === "cashflow-create" ? "new" : currentWidgetId,
        title: title.trim(),
        selectedBankIds: selectedBankIds.length > 0 ? selectedBankIds : bankIds,
        selectedAssetIds: selectedAssetIds.length > 0 ? selectedAssetIds : assetCodes,
        eventTypes: filters!.eventTypes,
        structureStatusIds: filters!.structureStatusIds,
        dateFrom: range.dateFrom,
        dateTo: range.dateTo,
      });
      toast.success(operation === "cashflow-create" ? "Cashflow widget added" : "Cashflow widget saved");
      onWidgetsChanged?.();
      onClose();
    } catch (saveError) {
      toastApiError(saveError, "Cashflow widget could not be saved.");
    } finally {
      setBusy(false);
    }
  }

  // Match AA / CH / DIY embedded Configure card chrome.
  return (
    <div className="overflow-hidden rounded-lg border bg-card">
      <div className="space-y-2 p-4">
        <Label>{isCreate ? "Widget title (optional)" : "Widget title"}</Label>
        <Input
          value={title}
          placeholder="Cashflow Calendar"
          onChange={(event) => setTitle(event.target.value)}
        />
      </div>

      <div className="border-t px-4 pt-3">
        <p className="text-muted-foreground text-xs">
          Calendar loads one month at a time. Next / previous fetch further months on demand
          (up to ±36 months).
        </p>
      </div>

      <div className="p-4 pt-3">
        <CashflowFiltersForm
          value={filters}
          onChange={setFilters}
          bankOptions={bankOptions}
          assetClassOptions={assetClassOptions}
          variant="settings"
        />
      </div>

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