/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

import type {
  CSSProperties,
  CompiledStyles,
  InlineStyles,
  Keyframes,
  MapNamespaces,
  NestedConstsValue,
  NestedStringValue,
  NestedVarsValue,
  StaticStyles,
  StaticStylesWithout,
  StyleX$Create,
  StyleX$CreateTheme,
  StyleX$DefineVars,
  StyleX$DefineConsts,
  StyleXArray,
  StyleXClassNameFor,
  StyleXStyles,
  StyleXStylesWithout,
  StyleXVar,
  Theme,
  VarGroup,
  PositionTry,
  ViewTransitionClass,
  StyleX$When,
  MapNamespace,
  StyleX$DefineMarker,
  StyleX$Env,
} from './types/StyleXTypes';
import type { ValueWithDefault } from './types/StyleXUtils';
import * as Types from './types/VarTypes';

export type {
  CSSProperties,
  CompiledStyles,
  InlineStyles,
  Keyframes,
  MapNamespaces,
  StaticStyles,
  StaticStylesWithout,
  StyleXArray,
  StyleXClassNameFor,
  StyleXStyles,
  StyleXStylesWithout,
  StyleXVar,
  Theme,
  Types,
  VarGroup,
  PositionTry,
};

declare export const create: StyleX$Create;

declare export const createTheme: StyleX$CreateTheme;

declare export const defineConsts: StyleX$DefineConsts;

declare export const defineVars: StyleX$DefineVars;

declare export const unstable_conditional: <
  const T extends { readonly default: unknown, readonly [string]: unknown },
>(
  _value: T,
) => T;

declare export const unstable_defineVarsNested: <
  const T extends { readonly [string]: NestedVarsValue },
>(
  _styles: T,
) => T;

declare export const unstable_defineConstsNested: <
  const T extends { readonly [string]: NestedConstsValue },
>(
  _styles: T,
) => T;

declare export const unstable_createThemeNested: (
  _baseTokens: { readonly [string]: NestedStringValue },
  _overrides: { readonly [string]: NestedVarsValue },
) => CompiledStyles;

declare export const defineMarker: StyleX$DefineMarker;

declare export const firstThatWorks: <T extends string | number>(
  ..._styles: ReadonlyArray<T>
) => ReadonlyArray<T>;

declare export const keyframes: (_keyframes: Keyframes) => string;

declare export const positionTry: (_positionTry: PositionTry) => string;

declare export function props(
  this: ?unknown,
  ...styles: ReadonlyArray<
    StyleXArray<
      ?CompiledStyles | boolean | Readonly<[CompiledStyles, InlineStyles]>,
    >,
  >
): Readonly<{
  className?: string,
  'data-style-src'?: string,
  style?: Readonly<{ [string]: string | number }>,
}>;

declare export function attrs(
  this: ?unknown,
  ...styles: ReadonlyArray<
    StyleXArray<
      ?CompiledStyles | boolean | Readonly<[CompiledStyles, InlineStyles]>,
    >,
  >
): Readonly<{
  class?: string,
  'data-style-src'?: string,
  style?: string,
}>;

declare export const viewTransitionClass: (
  _viewTransitionClass: ViewTransitionClass,
) => string;

declare export const defaultMarker: () => MapNamespace<
  Readonly<{
    marker: 'default-marker',
  }>,
>;

declare export const when: StyleX$When;

declare export const env: StyleX$Env;

declare export const types: {
  angle: <T extends string | 0 = string | 0>(
    _v: ValueWithDefault<T>,
  ) => Types.Angle<T>,
  color: <T extends string = string>(_v: ValueWithDefault<T>) => Types.Color<T>,
  url: <T extends string = string>(_v: ValueWithDefault<T>) => Types.Url<T>,
  image: <T extends string = string>(_v: ValueWithDefault<T>) => Types.Image<T>,
  integer: <T extends number = number>(
    _v: ValueWithDefault<T>,
  ) => Types.Integer<T>,
  lengthPercentage: <T extends number | string = number | string>(
    _v: ValueWithDefault<T>,
  ) => Types.LengthPercentage<T>,
  length: <T extends number | string = number | string>(
    _v: ValueWithDefault<T>,
  ) => Types.Length<T>,
  percentage: <T extends number | string = number | string>(
    _v: ValueWithDefault<T>,
  ) => Types.Percentage<T>,
  number: <T extends number = number>(_v: ValueWithDefault<T>) => Types.Num<T>,
  resolution: <T extends string = string>(
    _v: ValueWithDefault<T>,
  ) => Types.Resolution<T>,
  time: <T extends string | 0 = string | 0>(
    _v: ValueWithDefault<T>,
  ) => Types.Time<T>,
  transformFunction: <T extends string = string>(
    _v: ValueWithDefault<T>,
  ) => Types.TransformFunction<T>,
  transformList: <T extends string = string>(
    _v: ValueWithDefault<T>,
  ) => Types.TransformList<T>,
};

/**
 * DO NOT USE. Legacy export for Meta
 */

type IStyleX = {
  (...styles: ReadonlyArray<StyleXArray<?CompiledStyles | boolean>>): string,
  create: StyleX$Create,
  createTheme: StyleX$CreateTheme,
  defineConsts: StyleX$DefineConsts,
  defineVars: StyleX$DefineVars,
  env: StyleX$Env,
  defaultMarker: () => MapNamespace<
    Readonly<{
      marker: 'default-marker',
    }>,
  >,
  defineMarker: StyleX$DefineMarker,
  firstThatWorks: <T extends string | number>(
    ...v: ReadonlyArray<T>
  ) => ReadonlyArray<T>,
  keyframes: (keyframes: Keyframes) => string,
  positionTry: (positionTry: PositionTry) => string,
  props: (
    this: ?unknown,
    ...styles: ReadonlyArray<
      StyleXArray<
        ?CompiledStyles | boolean | Readonly<[CompiledStyles, InlineStyles]>,
      >,
    >
  ) => Readonly<{
    className?: string,
    'data-style-src'?: string,
    style?: Readonly<{ [string]: string | number }>,
  }>,
  attrs: (
    this: ?unknown,
    ...styles: ReadonlyArray<
      StyleXArray<
        ?CompiledStyles | boolean | Readonly<[CompiledStyles, InlineStyles]>,
      >,
    >
  ) => Readonly<{
    class?: string,
    'data-style-src'?: string,
    style?: string,
  }>,
  viewTransitionClass: (viewTransitionClass: ViewTransitionClass) => string,
  types: typeof types,
  when: typeof when,
  unstable_conditional: <
    const T extends { readonly default: unknown, readonly [string]: unknown },
  >(
    value: T,
  ) => T,
  unstable_defineVarsNested: <
    const T extends { readonly [string]: NestedVarsValue },
  >(
    tokens: T,
  ) => T,
  unstable_defineConstsNested: <
    const T extends { readonly [string]: NestedConstsValue },
  >(
    tokens: T,
  ) => T,
  unstable_createThemeNested: (
    baseTokens: { readonly [string]: NestedStringValue },
    overrides: { readonly [string]: NestedVarsValue },
  ) => CompiledStyles,
  __customProperties?: { [string]: unknown },
  ...
};

declare export const legacyMerge: IStyleX;
