/**
 * 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
 * @format
 */

'use strict';

import Platform from '../../../exports/Platform';
import UIManager from '../../../exports/UIManager';
const __DEV__ = process.env.NODE_ENV !== 'production';
type Type = 'spring' | 'linear' | 'easeInEaseOut' | 'easeIn' | 'easeOut' | 'keyboard';
type Property = 'opacity' | 'scaleX' | 'scaleY' | 'scaleXY';
type AnimationConfig = $ReadOnly<{|
  duration?: number,
  delay?: number,
  springDamping?: number,
  initialVelocity?: number,
  type?: Type,
  property?: Property,
|}>;
type LayoutAnimationConfig = $ReadOnly<{|
  duration: number,
  create?: AnimationConfig,
  update?: AnimationConfig,
  delete?: AnimationConfig,
|}>;
declare function configureNext(config: LayoutAnimationConfig, onAnimationDidEnd?: Function): any;
declare function create(duration: number, type: Type, property: Property): LayoutAnimationConfig;
const Presets = {
  easeInEaseOut: (create(300, 'easeInEaseOut', 'opacity'): LayoutAnimationConfig),
  linear: (create(500, 'linear', 'opacity'): LayoutAnimationConfig),
  spring: {
    duration: 700,
    create: {
      type: 'linear',
      property: 'opacity'
    },
    update: {
      type: 'spring',
      springDamping: 0.4
    },
    delete: {
      type: 'linear',
      property: 'opacity'
    }
  }
};

/**
 * Automatically animates views to their new positions when the
 * next layout happens.
 *
 * A common way to use this API is to call it before calling `setState`.
 *
 * Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
 *
 *     UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
 */
const LayoutAnimation = {
  /**
   * Schedules an animation to happen on the next layout.
   *
   * @param config Specifies animation properties:
   *
   *   - `duration` in milliseconds
   *   - `create`, `AnimationConfig` for animating in new views
   *   - `update`, `AnimationConfig` for animating views that have been updated
   *
   * @param onAnimationDidEnd Called when the animation finished.
   * Only supported on iOS.
   * @param onError Called on error. Only supported on iOS.
   */
  configureNext,
  /**
   * Helper for creating a config for `configureNext`.
   */
  create,
  Types: Object.freeze({
    spring: 'spring',
    linear: 'linear',
    easeInEaseOut: 'easeInEaseOut',
    easeIn: 'easeIn',
    easeOut: 'easeOut',
    keyboard: 'keyboard'
  }),
  Properties: Object.freeze({
    opacity: 'opacity',
    scaleX: 'scaleX',
    scaleY: 'scaleY',
    scaleXY: 'scaleXY'
  }),
  checkConfig(...args: Array<mixed>) {
    console.error('LayoutAnimation.checkConfig(...) has been disabled.');
  },
  Presets,
  easeInEaseOut: (configureNext.bind(null, Presets.easeInEaseOut): (onAnimationDidEnd?: any) => void),
  linear: (configureNext.bind(null, Presets.linear): (onAnimationDidEnd?: any) => void),
  spring: (configureNext.bind(null, Presets.spring): (onAnimationDidEnd?: any) => void)
};
export default LayoutAnimation;