import { ApolloClient, NormalizedCacheObject } from '@apollo/client';
import { IData } from '@assets/js-shop/GraphQLInterfaces';
import { ReactElement } from 'react';
import config from '@assets/js-shop/config';

export type IJsShopConfig = typeof config;

export interface IShopDataContext extends IData {
   loading: boolean;
   updateShopData: (
      data: Partial<IData> | ((prevData: Readonly<IData>) => Partial<IData>),
      callback?: () => void,
   ) => void;
   addToast: (toast: IToast) => void;
   client: ApolloClient<NormalizedCacheObject>;
}

export interface IAddedProduct {
   productId: number;
   variationId?: number;
   note?: object;
}

export interface IAddedProductPieces extends IAddedProduct {
   pieces: number;
}

export interface IAddProductAdditionalData {
   [key: string]: any;
}

export interface IAddProductOptions {
   buttonElement?: any;
   openCart?: boolean;
   additionalData?: IAddProductAdditionalData;
   blockingPromise?: boolean; // promise will be resolved after the product is successfully added
}

export const ToastType = {
   Classic: 'classic',
   Computed: 'computed',
} as const;
export type ToastType = (typeof ToastType)[keyof typeof ToastType];

export const ToastStatus = {
   Success: 'success',
   Error: 'error',
   Warning: 'warning',
   Info: 'info',
} as const;
export type ToastStatus = (typeof ToastStatus)[keyof typeof ToastStatus];

export interface IToast {
   content: ReactElement | string;
   type: ToastType;
   status: ToastStatus;
   referenceElement?: any;
}

export const JsShopRefreshEventName = 'jsShop:refresh';
export type JsShopRefreshEventDetail = {
   scope: RefreshScopeEnum;
};

export enum RefreshScopeEnum {
   All = 'all',
   Favorites = 'favorites',
   CartDetail = 'cart-detail',
}

export interface WrappedPromise<T> {
   promise: Promise<T>;
   resolve: (value: T) => void;
   reject: (reason?: any) => void;
   isResolved: boolean;
   isUnresolved: boolean;
}
