import type { I18n } from '@lingui/core';
import type { MantineColorScheme, MantineTheme } from '@mantine/core';
import type { QueryClient } from '@tanstack/react-query';
import type { AxiosInstance } from 'axios';
import type { NavigateFunction } from 'react-router-dom';
import type { ModelDict } from '../enums/ModelInformation';
import type { ModelType } from '../enums/ModelType';
import type {
  ApiFormModalProps,
  BulkEditApiFormModalProps,
  StockOperationProps
} from './Forms';
import type { UseModalReturn } from './Modals';
import type { RenderInstanceProps } from './Rendering';
import type { SettingsStateProps } from './Settings';
import type { InvenTreeTableRenderProps } from './Tables';
import type { UserStateProps } from './User';

export interface PluginProps {
  name: string;
  slug: string;
  version: null | string;
}

export interface PluginVersion {
  inventree: string;
  react: string;
  reactDom: string;
  mantine: string;
}

export type StockAdjustmentFormsContext = {
  addStock: (props: StockOperationProps) => UseModalReturn;
  assignStock: (props: StockOperationProps) => UseModalReturn;
  changeStatus: (props: StockOperationProps) => UseModalReturn;
  countStock: (props: StockOperationProps) => UseModalReturn;
  deleteStock: (props: StockOperationProps) => UseModalReturn;
  mergeStock: (props: StockOperationProps) => UseModalReturn;
  removeStock: (props: StockOperationProps) => UseModalReturn;
  transferStock: (props: StockOperationProps) => UseModalReturn;
  returnStock: (props: StockOperationProps) => UseModalReturn;
};

export type InvenTreeFormsContext = {
  bulkEdit: (props: BulkEditApiFormModalProps) => UseModalReturn;
  create: (props: ApiFormModalProps) => UseModalReturn;
  delete: (props: ApiFormModalProps) => UseModalReturn;
  edit: (props: ApiFormModalProps) => UseModalReturn;
  stockActions: StockAdjustmentFormsContext;
};

export type InvenTreeTablesContext<T extends Record<string, any>> = {
  renderTable: (props: InvenTreeTableRenderProps<T>) => React.ReactNode;
};

export type ImporterDrawerContext = {
  open: (sessionId: number, options?: { onClose?: () => void }) => void;
  close: () => void;
  isOpen: () => boolean;
  sessionId: () => number | null;
};

/**
 * A set of properties which are passed to a plugin,
 * for rendering an element in the user interface.
 *
 * @param version - The version of the running InvenTree software stack
 * @param api - The Axios API instance (see ../states/ApiState.tsx)
 * @param queryClient - The Tanstack QueryClient instance (see ../states/QueryState.tsx)
 * @param user - The current user instance (see ../states/UserState.tsx)
 * @param userSettings - The current user settings (see ../states/SettingsState.tsx)
 * @param globalSettings - The global settings (see ../states/SettingsState.tsx)
 * @param modelInformation - A dictionary of available model information
 * @param renderInstance - A component function for rendering a model instance
 * @param host - The current host URL
 * @param i18n - The i18n instance for translations (from @lingui/core)
 * @param locale - The current locale string (e.g. 'en' / 'de')
 * @param navigate - The navigation function (see react-router-dom)
 * @param theme - The current Mantine theme
 * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark')
 * @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx)
 * @param tables - A set of functions for rendering API tables
 * @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx)
 * @param model - The model type associated with the rendered component (if applicable)
 * @param id - The ID (primary key) of the model instance for the plugin (if applicable)
 * @param instance - The model instance data (if available)
 * @param reloadContent - A function which can be called to reload the plugin content
 * @param reloadInstance - A function which can be called to reload the model instance
 * @param context - Any additional context data which may be passed to the plugin
 */
export type InvenTreePluginContext = {
  version: PluginVersion;
  api: AxiosInstance;
  queryClient: QueryClient;
  user: UserStateProps;
  userSettings: SettingsStateProps;
  globalSettings: SettingsStateProps;
  modelInformation: ModelDict;
  renderInstance: (props: Readonly<RenderInstanceProps>) => React.ReactNode;
  host: string;
  i18n: I18n;
  locale: string;
  navigate: NavigateFunction;
  theme: MantineTheme;
  colorScheme: MantineColorScheme;
  forms: InvenTreeFormsContext;
  tables: InvenTreeTablesContext<any>;
  importer: ImporterDrawerContext;
  model?: ModelType | string;
  id?: string | number | null;
  instance?: any;
  reloadContent?: () => void;
  reloadInstance?: () => void;
  context?: any;
};

/*
 * The version of the InvenTree plugin context interface.
 * This number should be incremented if the interface changes.
 */

// @ts-ignore
export const INVENTREE_PLUGIN_VERSION: string = __INVENTREE_LIB_VERSION__;
// @ts-ignore
export const INVENTREE_REACT_VERSION: string = __INVENTREE_REACT_VERSION__;
// @ts-ignore
export const INVENTREE_REACT_DOM_VERSION: string =
  // @ts-ignore
  __INVENTREE_REACT_DOM_VERSION__;
// @ts-ignore
export const INVENTREE_MANTINE_VERSION: string = __INVENTREE_MANTINE_VERSION__;
