import { createContext, ProviderProps, useContext } from 'react';

/**
 * 上下文中的数据源描述器
 */
export type SourceContextValue = {
  /*
   * 根据上下文返回要修改的字段或输入的源
   */
  getSource: (source: string) => string;

  /*
   * 根据上下文返回要修改的字段或输入的标签，我们
   * 可以配合 i18n/i10n 返回一个翻译键。
   */
  getLabel: (source: string) => string;
};

const SourceContext = createContext<SourceContextValue | undefined>(undefined);

/**
 * 数据源描述提供器
 *
 * 允许一些特殊的输入为它们的子源添加前缀或后缀。
 *
 * @example
 *
 * ```jsx
 * const sourceContext = {
 *  getSource: source => `coordinates.${source}`,
 *  getLabel: source => `resources.posts.fields.${source}`,
 * }
 *
 * const CoordinatesInput = () => {
 *   return (
 *     <SourceContextProvider value={sourceContext}>
 *       <TextInput source="lat" />
 *       <TextInput source="lng" />
 *     </SourceContextProvider>
 *   );
 * };
 * ```
 */
export function SourceContextProvider({ children, value }: ProviderProps<SourceContextValue>) {
  return (
    <SourceContext value={value}>
      {children}
    </SourceContext>
  );
}

const defaultContextValue: SourceContextValue = {
  getSource: (source: string) => source,
  getLabel: (source: string) => source,
};

export function useSourceContext(): SourceContextValue {
  const context = useContext(SourceContext);
  return context ?? defaultContextValue;
}

export function useOptionalSourceContext(): SourceContextValue | undefined {
  return useContext(SourceContext);
}
