import { type ReactNode } from "react";
import type { IndieTabletopClient } from "../client.ts";
import { createStrictContext } from "../createStrictContext.ts";
import type { AppHrefs } from "../hrefs.ts";
import type { ModernIDB } from "../ModernIDB/index.ts";
import type { DatabaseAppMachineMethods } from "../store/index.tsx";
import type { AppkitFormatters } from "./formatters.tsx";

export type AppConfig = {
  app: {
    /**
     * The app's name, e.g. Space Gits. Do not include the word App in this
     * title -- it will be added automatically in places where it's needed.
     */
    name: string;

    /**
     * The URL to the app's icon. This should be a maskable-style icon. In
     * other words, it should not include its own transparency.
     */
    icon: string;
  };

  /**
   * Usually the value of `import.meta.env.DEV` when using Vite.
   *
   * This is used primarily by the DocumentTitle component, to make it clear
   * which browser tab is in DEV mode.
   */
  isDev: boolean;

  /**
   * A reference to the ITC client.
   *
   * This is necessary in order for prefab components to make thier own calls.
   */
  client: IndieTabletopClient;

  /**
   * A hrefs configuration.
   *
   * This is necessary so that prefab components can navigate around the app
   * without hard-coded values.
   */
  hrefs: AppHrefs;

  /**
   * Customize input placeholders so that they fit their given app thematically.
   */
  placeholders: {
    email: string;
  };

  /**
   * Formatters accessible to prefab components.
   *
   * You might want to create different formatters based on the app's locale.
   */
  fmt: AppkitFormatters;

  database: ModernIDB<any, any> & DatabaseAppMachineMethods<any>;
};

const [AppConfigContext, useAppConfig] = createStrictContext<AppConfig>();

export { createFormatters } from "./formatters.tsx";

export { useAppConfig };

export function useClient() {
  return useAppConfig().client;
}

export function AppConfigProvider(props: {
  config: AppConfig;
  children: ReactNode;
}) {
  const { config, children } = props;
  return <AppConfigContext value={config}>{children}</AppConfigContext>;
}
