"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { useState, useEffect, useCallback, useMemo } from "react";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader, extractOptimisticLockConflict } from "@open-mercato/ui/backend/utils/optimisticLock";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { Button } from "@open-mercato/ui/primitives/button";
import { Spinner } from "@open-mercato/ui/primitives/spinner";
import { Switch } from "@open-mercato/ui/primitives/switch";
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
import { Alert } from "@open-mercato/ui/primitives/alert";
import { TimeInput } from "@open-mercato/ui/backend/inputs/TimeInput";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("currencies").child({ component: "CurrencyFetchingConfig" });
const STATUS_BADGE_VARIANT = {
  success: "success",
  error: "error",
  partial: "warning"
};
function CurrencyFetchingConfig() {
  const t = useT();
  const [configs, setConfigs] = useState([]);
  const [loading, setLoading] = useState(true);
  const [fetching, setFetching] = useState(null);
  const [initializing, setInitializing] = useState(false);
  const availableProviders = useMemo(() => ["NBP", "Raiffeisen Bank Polska"], []);
  const mutationContextId = "currencies-fetch-configs:mutation";
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: mutationContextId,
    blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const createProviderConfig = useCallback(async (provider) => {
    try {
      await runMutation({
        operation: () => apiCall("/api/currencies/fetch-configs", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            provider,
            isEnabled: false,
            syncTime: "09:00"
          })
        }),
        context: {
          formId: mutationContextId,
          resourceKind: "currencies.fetch_config",
          retryLastMutation
        },
        mutationPayload: { provider, isEnabled: false, syncTime: "09:00" }
      });
    } catch (err) {
      if (!err.message?.includes("already configured")) {
        throw err;
      }
    }
  }, [mutationContextId, retryLastMutation, runMutation]);
  const initializeMissingProviders = useCallback(async (providers) => {
    setInitializing(true);
    try {
      for (const provider of providers) {
        await createProviderConfig(provider);
      }
      const { result } = await apiCall("/api/currencies/fetch-configs");
      if (result?.configs) {
        setConfigs(result.configs);
      }
    } catch (err) {
      logger.error("Failed to initialize providers", { err });
    } finally {
      setInitializing(false);
    }
  }, [createProviderConfig]);
  const loadConfigs = useCallback(async () => {
    try {
      const { result } = await apiCall("/api/currencies/fetch-configs");
      if (result?.configs) {
        const existingConfigs = result.configs;
        setConfigs(existingConfigs);
        const existingProviders = existingConfigs.map((c) => c.provider);
        const missingProviders = availableProviders.filter(
          (p) => !existingProviders.includes(p)
        );
        if (missingProviders.length > 0) {
          await initializeMissingProviders(missingProviders);
        }
      }
    } catch (err) {
      flash(err.message || t("currencies.fetch.error_load_configs"), "error");
    } finally {
      setLoading(false);
    }
  }, [availableProviders, initializeMissingProviders, t]);
  const toggleEnabled = useCallback(async (configId, currentValue, updatedAt) => {
    try {
      const call = await runMutation({
        operation: async () => {
          const response = await withScopedApiRequestHeaders(
            buildOptimisticLockHeader(updatedAt),
            () => apiCall("/api/currencies/fetch-configs", {
              method: "PUT",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                id: configId,
                isEnabled: !currentValue
              })
            })
          );
          if (!response.ok) {
            throw Object.assign(new Error("[internal] currencies.fetchConfig.toggle failed"), {
              status: response.status,
              ...response.result ?? {}
            });
          }
          return response;
        },
        context: {
          formId: mutationContextId,
          resourceKind: "currencies.fetch_config",
          resourceId: configId,
          retryLastMutation
        },
        mutationPayload: { id: configId, isEnabled: !currentValue }
      });
      const result = call.result;
      if (result?.config) {
        setConfigs(
          (prev) => prev.map((c) => c.id === configId ? result.config : c)
        );
        flash(
          currentValue ? t("currencies.fetch.provider_disabled") : t("currencies.fetch.provider_enabled"),
          "success"
        );
      }
    } catch (err) {
      if (extractOptimisticLockConflict(err)) return;
      flash(err.message || t("currencies.fetch.error_update_config"), "error");
    }
  }, [mutationContextId, retryLastMutation, runMutation, t]);
  const updateSyncTime = useCallback(async (configId, syncTime, updatedAt) => {
    try {
      const call = await runMutation({
        operation: async () => {
          const response = await withScopedApiRequestHeaders(
            buildOptimisticLockHeader(updatedAt),
            () => apiCall("/api/currencies/fetch-configs", {
              method: "PUT",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                id: configId,
                syncTime: syncTime || null
              })
            })
          );
          if (!response.ok) {
            throw Object.assign(new Error("[internal] currencies.fetchConfig.updateSyncTime failed"), {
              status: response.status,
              ...response.result ?? {}
            });
          }
          return response;
        },
        context: {
          formId: mutationContextId,
          resourceKind: "currencies.fetch_config",
          resourceId: configId,
          retryLastMutation
        },
        mutationPayload: { id: configId, syncTime: syncTime || null }
      });
      const result = call.result;
      if (result?.config) {
        setConfigs(
          (prev) => prev.map((c) => c.id === configId ? result.config : c)
        );
      }
    } catch (err) {
      if (extractOptimisticLockConflict(err)) return;
      flash(err.message || t("currencies.fetch.error_update_sync_time"), "error");
    }
  }, [mutationContextId, retryLastMutation, runMutation, t]);
  const fetchNow = useCallback(async (provider) => {
    setFetching(provider);
    try {
      const call = await runMutation({
        operation: () => apiCall("/api/currencies/fetch-rates", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            providers: [provider]
          })
        }),
        context: {
          formId: mutationContextId,
          resourceKind: "currencies.fetch_rates",
          retryLastMutation
        },
        mutationPayload: { providers: [provider] }
      });
      const result = call.result;
      if (result) {
        const byProvider = result.byProvider;
        const count = byProvider?.[provider]?.count || 0;
        if (count === 0) {
          flash(t("currencies.fetch.sync_no_rates"), "warning");
        } else {
          flash(t("currencies.fetch.sync_success", { count }), "success");
        }
        await loadConfigs();
      }
    } catch (err) {
      flash(err.message || t("currencies.fetch.sync_error"), "error");
    } finally {
      setFetching(null);
    }
  }, [mutationContextId, retryLastMutation, runMutation, t, loadConfigs]);
  useEffect(() => {
    loadConfigs();
  }, [loadConfigs]);
  function formatLastSync(date) {
    if (!date) return t("currencies.fetch.last_sync_never");
    return new Date(date).toLocaleString();
  }
  function getStatusBadge(status) {
    if (!status) return null;
    return /* @__PURE__ */ jsx(StatusBadge, { variant: STATUS_BADGE_VARIANT[status] ?? "neutral", children: status });
  }
  function getProviderName(provider) {
    if (provider === "NBP") return t("currencies.fetch.provider_nbp");
    if (provider === "Raiffeisen Bank Polska") return t("currencies.fetch.provider_raiffeisen");
    return provider;
  }
  function getProviderDescription(provider) {
    if (provider === "NBP") {
      return t("currencies.fetch.provider_nbp_description");
    }
    if (provider === "Raiffeisen Bank Polska") {
      return t("currencies.fetch.provider_raiffeisen_description");
    }
    return "";
  }
  if (loading || initializing) {
    return /* @__PURE__ */ jsxs("section", { className: "space-y-3 rounded-lg border bg-background p-4", children: [
      /* @__PURE__ */ jsxs("header", { className: "space-y-2", children: [
        /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold", children: t("currencies.fetch.title") }),
        /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("currencies.fetch.description") })
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
        /* @__PURE__ */ jsx(Spinner, { className: "h-4 w-4" }),
        initializing ? t("currencies.fetch.initializing_providers") : t("currencies.fetch.loading")
      ] })
    ] });
  }
  return /* @__PURE__ */ jsxs("section", { className: "space-y-6 rounded-lg border bg-background p-4", children: [
    /* @__PURE__ */ jsxs("header", { className: "space-y-2", children: [
      /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold", children: t("currencies.fetch.title") }),
      /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("currencies.fetch.description") })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
      configs.map((config) => /* @__PURE__ */ jsxs(
        "div",
        {
          className: "rounded-lg border bg-card p-4",
          children: [
            /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
              /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
                /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: getProviderName(config.provider) }),
                /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: getProviderDescription(config.provider) })
              ] }),
              /* @__PURE__ */ jsx(
                Switch,
                {
                  checked: config.isEnabled,
                  onCheckedChange: () => toggleEnabled(config.id, config.isEnabled, config.updatedAt)
                }
              )
            ] }),
            config.isEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
              /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-3 flex-wrap mt-3", children: [
                /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
                  /* @__PURE__ */ jsxs("label", { className: "text-xs text-muted-foreground whitespace-nowrap", children: [
                    t("currencies.fetch.sync_time"),
                    ":"
                  ] }),
                  /* @__PURE__ */ jsx(
                    TimeInput,
                    {
                      value: config.syncTime || "09:00",
                      onChange: (time) => updateSyncTime(config.id, time, config.updatedAt)
                    }
                  )
                ] }),
                /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
                  /* @__PURE__ */ jsxs("label", { className: "text-xs text-muted-foreground whitespace-nowrap", children: [
                    t("currencies.fetch.last_sync"),
                    ":"
                  ] }),
                  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatLastSync(config.lastSyncAt) }),
                  getStatusBadge(config.lastSyncStatus)
                ] }),
                /* @__PURE__ */ jsx(
                  Button,
                  {
                    type: "button",
                    onClick: () => fetchNow(config.provider),
                    disabled: fetching === config.provider,
                    size: "default",
                    className: "ml-auto min-w-32",
                    children: fetching === config.provider ? /* @__PURE__ */ jsxs("div", { children: [
                      /* @__PURE__ */ jsx(Spinner, { className: "mr-1.5", size: "sm" }),
                      t("currencies.fetch.fetching")
                    ] }) : t("currencies.fetch.fetch_now")
                  }
                )
              ] }),
              config.lastSyncCount !== null && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground mt-2", children: [
                t("currencies.fetch.last_sync_count"),
                ": ",
                /* @__PURE__ */ jsx("span", { className: "font-medium", children: config.lastSyncCount })
              ] }),
              config.lastSyncMessage && config.lastSyncStatus === "error" && /* @__PURE__ */ jsx(Alert, { status: "error", style: "lighter", size: "xs", className: "mt-2", children: config.lastSyncMessage })
            ] })
          ]
        },
        config.id
      )),
      configs.length === 0 && /* @__PURE__ */ jsxs("div", { className: "rounded border bg-background/80 p-6 text-center", children: [
        /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("currencies.fetch.no_providers") }),
        /* @__PURE__ */ jsx(
          Button,
          {
            type: "button",
            onClick: () => initializeMissingProviders(availableProviders),
            children: t("currencies.fetch.initialize_providers")
          }
        )
      ] })
    ] })
  ] });
}
export {
  CurrencyFetchingConfig as default
};
//# sourceMappingURL=CurrencyFetchingConfig.js.map
