import type {
  App,
  Component,
  ComputedRef,
  DefineComponent,
  Plugin,
  Ref,
} from 'vue';

type MaybeRef<T> = T | Ref<T>;
type InstallableComponent<T extends Component = DefineComponent> = T & Plugin;

export interface LocaleMessages {
  name: string;
  [key: string]: unknown;
}

export interface LocaleContext {
  lang: ComputedRef<string>;
  locale: Ref<LocaleMessages>;
  t: (path: string, option?: Record<string, unknown>) => string;
}

export const configProviderContextKey: symbol;
export const zIndexContextKey: symbol;
export const sizeInjectionKey: symbol;
export const localeContextKey: symbol;
export const defaultNamespace: string;
export const defaultInitialZIndex: number;

export function useGlobalConfig<T = unknown>(
  key: string,
  defaultValue?: T,
): ComputedRef<T>;
export function useGlobalConfig<T = Record<string, unknown>>(): Ref<T | undefined>;

export function useGlobalComponentSettings(
  sizeFallback?: MaybeRef<string | undefined>,
): {
  locale: LocaleContext;
  zIndex: number;
  size: ComputedRef<string>;
};

export function provideGlobalConfig<T extends Record<string, unknown>>(
  config: MaybeRef<T>,
  app?: App,
  global?: boolean,
): ComputedRef<T> | void;

export function buildTranslator(
  locale: MaybeRef<LocaleMessages>,
): (path: string, option?: Record<string, unknown>) => string;

export function translate(
  path: string,
  option: Record<string, unknown> | undefined,
  locale: LocaleMessages,
): string;

export function buildLocaleContext(locale: MaybeRef<LocaleMessages>): LocaleContext;
export function useLocale(localeOverrides?: Ref<LocaleMessages | undefined>): LocaleContext;

export const zhCN: LocaleMessages;
export const enUS: LocaleMessages;
export const jaJP: LocaleMessages;

export const GscConfigProvider: InstallableComponent;
export const GscCodeEditor: InstallableComponent;
export const GscScaleScreen: InstallableComponent;
export const GscVideoBackground: InstallableComponent;
export const GscGrid: InstallableComponent;
export const GscForm: InstallableComponent;
export const GscButton: InstallableComponent;
export const GscCountTo: InstallableComponent;
export const GscMarquee: InstallableComponent;
export const GscVideoPlayer: InstallableComponent;
export const GscEllipsis: InstallableComponent;
export const GscVirtualScroll: InstallableComponent;
export const GscRichTextEditor: InstallableComponent;
export const GscProgress: InstallableComponent;

export const GscCollapseTransition: InstallableComponent;
export const GscFadeTransition: InstallableComponent;
export const GscScaleTransition: InstallableComponent;
export const GscSlideYTransition: InstallableComponent;
export const GscScrollYTransition: InstallableComponent;
export const GscSlideYReverseTransition: InstallableComponent;
export const GscScrollYReverseTransition: InstallableComponent;
export const GscSlideXTransition: InstallableComponent;
export const GscScrollXTransition: InstallableComponent;
export const GscSlideXReverseTransition: InstallableComponent;
export const GscScrollXReverseTransition: InstallableComponent;
export const GscScaleRotateTransition: InstallableComponent;
export const GscExpandXTransition: InstallableComponent;
export const GscExpandTransition: InstallableComponent;

export const Modal: DefineComponent;
export const Message: DefineComponent;
export const Notice: DefineComponent;
export const Tooltip: DefineComponent;

export function showMessage(options?: Record<string, unknown>): unknown;
export function showNotice(options?: Record<string, unknown>): unknown;
export function openModal(
  props?: Record<string, unknown>,
  slots?: Record<string, unknown | (() => unknown)>,
): {
  close: () => void;
};

declare const componentsPlugin: Plugin;

export default componentsPlugin;
