import { api, CachedRequest } from '@blocklet/payment-react';
import type { TProductExpanded } from '@blocklet/payment-types';
import { Alert, CircularProgress } from '@mui/material';
import { useRequest } from 'ahooks';
import { createContext, useContext, type JSX } from 'react';
import useBus from 'use-bus';

type ProductsContextType = {
  products: TProductExpanded[];
  refresh: (forceRefresh?: boolean) => void;
};

// @ts-ignore
const ProductsContext = createContext<ProductsContextType>({ api });
const { Provider, Consumer } = ProductsContext;

const fetchProducts = (forceRefresh = false): Promise<{ list: TProductExpanded[] }> => {
  const livemode = localStorage.getItem('livemode') !== 'false';
  const cacheKey = `products-${livemode}`;

  const cachedRequest = new CachedRequest(
    cacheKey,
    () => api.get('/api/products?active=true&page=1&pageSize=100&donation=hide'),
    {
      ttl: 1000 * 60 * 10, // 10分钟缓存
      strategy: 'session',
    }
  );

  return cachedRequest.fetch(forceRefresh);
};

// eslint-disable-next-line react/prop-types
function ProductsProvider({ children }: { children: any }): JSX.Element {
  const { data, error, run, loading } = useRequest((forceRefresh = false) => fetchProducts(forceRefresh));
  useBus('product.created', () => run(true), []);
  useBus('product.updated', () => run(true), []);
  useBus('product.deleted', () => run(true), []);
  useBus('price.created', () => run(true), []);
  useBus('price.updated', () => run(true), []);
  useBus('price.deleted', () => run(true), []);
  if (error) {
    return <Alert severity="error">{error.message}</Alert>;
  }

  if (loading || !data) {
    return <CircularProgress />;
  }

  return <Provider value={{ products: data?.list ?? [], refresh: () => run(true) }}>{children}</Provider>;
}

function useProductsContext() {
  const context = useContext(ProductsContext);
  return context;
}

export const clearProductsCache = () => {
  const livemode = localStorage.getItem('livemode') !== 'false';
  const cacheKey = `products-${livemode}`;
  sessionStorage.removeItem(cacheKey);
};

export { ProductsContext, ProductsProvider, Consumer as ProductsConsumer, useProductsContext };
