import { jsx } from "react/jsx-runtime";
import { Alert } from "@mui/material";
import { useLocalStorageState, useRequest } from "ahooks";
import { createContext, useContext, useEffect, useState } from "react";
import axios from "axios";
import { joinURL } from "ufo";
import useBus from "use-bus";
import api from "../libs/api.js";
import { getPrefix, PAYMENT_KIT_DID } from "../libs/util.js";
import { CachedRequest } from "../libs/cached-request.js";
const formatData = (data) => {
  if (!data) {
    return {
      paymentMethods: [],
      baseCurrency: {}
    };
  }
  return {
    ...data,
    paymentMethods: data.paymentMethods || [],
    baseCurrency: data.baseCurrency || {}
  };
};
const PaymentContext = createContext({ api });
const { Provider, Consumer } = PaymentContext;
const getSettings = (forceRefresh = false) => {
  const livemode = localStorage.getItem("livemode") !== "false";
  const cacheKey = `payment-settings-${window.location.pathname}-${livemode}`;
  const cachedRequest = new CachedRequest(cacheKey, () => api.get("/api/settings", { params: { livemode } }));
  return cachedRequest.fetch(forceRefresh);
};
const getCurrency = (currencyId, methods) => {
  const currencies = methods.reduce((acc, x) => acc.concat(x.payment_currencies), []);
  return currencies.find((x) => x.id === currencyId);
};
const getMethod = (methodId, methods) => {
  return methods.find((x) => x.id === methodId);
};
const syncToSpaceRequest = (userDid, spaceDid) => {
  const cacheKey = `sync-space-${userDid}-${spaceDid}`;
  const cachedRequest = new CachedRequest(cacheKey, () => api.post("/api/customers/sync-to-space"), {
    ttl: 1e3 * 60 * 60
    // 1 hour
  });
  return cachedRequest.fetch(false).then((res) => {
    if (!res.success) {
      cachedRequest.clearCache();
    }
    return res;
  });
};
function PaymentProvider({
  session,
  connect,
  children,
  baseUrl = void 0,
  authToken = void 0
}) {
  const [crossOriginLoading, setCrossOriginLoading] = useState(false);
  if (authToken) {
    window.__PAYMENT_KIT_AUTH_TOKEN = authToken;
  } else {
    window.__PAYMENT_KIT_AUTH_TOKEN = "";
  }
  useEffect(() => {
    const fetchCrossOriginBlockletInfo = async () => {
      if (!baseUrl) {
        window.__PAYMENT_KIT_BASE_URL = "";
        setCrossOriginLoading(false);
        return;
      }
      const tmp = new URL(baseUrl);
      if (tmp.origin === window.location.origin) {
        window.__PAYMENT_KIT_BASE_URL = "";
        setCrossOriginLoading(false);
        return;
      }
      setCrossOriginLoading(true);
      try {
        const scriptUrl = joinURL(tmp.origin, "__blocklet__.js?type=json");
        const cacheKey = `cross-origin-blocklet-${tmp.origin}`;
        const cachedRequest = new CachedRequest(
          cacheKey,
          () => axios.get(scriptUrl).then((res) => ({ data: res.data })),
          {
            strategy: "session",
            ttl: 10 * 60 * 1e3
            // 10 minutes TTL
          }
        );
        const blockletInfo = await cachedRequest.fetch();
        const componentId = (blockletInfo?.componentId || "").split("/").pop();
        if (componentId === PAYMENT_KIT_DID) {
          window.__PAYMENT_KIT_BASE_URL = joinURL(tmp.origin, blockletInfo.prefix || "/");
        } else {
          const component = (blockletInfo?.componentMountPoints || []).find((x) => x?.did === PAYMENT_KIT_DID);
          window.__PAYMENT_KIT_BASE_URL = component ? joinURL(tmp.origin, component.mountPoint) : baseUrl;
        }
      } catch (err) {
        console.warn(`Failed to fetch blocklet json from ${baseUrl}:`, err);
        window.__PAYMENT_KIT_BASE_URL = baseUrl;
      } finally {
        setCrossOriginLoading(false);
      }
    };
    fetchCrossOriginBlockletInfo();
  }, [baseUrl]);
  const [livemode, setLivemode] = useLocalStorageState("livemode", { defaultValue: true });
  const {
    data = {
      paymentMethods: [],
      baseCurrency: {}
    },
    error,
    run,
    loading
  } = useRequest(getSettings, {
    refreshDeps: [livemode]
  });
  useBus(
    // @ts-ignore
    ["paymentMethod.created", "paymentMethod.updated", "paymentCurrency.added", "paymentCurrency.updated"],
    () => run(true),
    [run]
  );
  useEffect(() => {
    const didSpace = session?.user?.didSpace;
    const userDid = session?.user?.did;
    if (userDid && didSpace && didSpace.endpoint && didSpace.did) {
      syncToSpaceRequest(userDid, didSpace.did);
    }
  }, [session?.user]);
  const prefix = getPrefix();
  const [payable, setPayable] = useState(true);
  const [paymentState, setPaymentState] = useState({
    paying: false,
    stripePaying: false
  });
  const updatePaymentState = (state) => {
    setPaymentState((prev) => ({ ...prev, ...state }));
  };
  if (error) {
    return /* @__PURE__ */ jsx(Alert, { severity: "error", children: error.message });
  }
  if (loading || crossOriginLoading) {
    return null;
  }
  return /* @__PURE__ */ jsx(
    Provider,
    {
      value: {
        session,
        connect,
        prefix,
        livemode: !!livemode,
        settings: formatData(data),
        getCurrency: (currencyId) => getCurrency(currencyId, data?.paymentMethods || []),
        getMethod: (methodId) => getMethod(methodId, data?.paymentMethods || []),
        refresh: run,
        setLivemode,
        api,
        payable,
        setPayable,
        paymentState,
        setPaymentState: updatePaymentState
      },
      children
    }
  );
}
function usePaymentContext() {
  const context = useContext(PaymentContext);
  return context;
}
export { PaymentContext, PaymentProvider, Consumer as SettingsConsumer, usePaymentContext };
