// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/widgets.dart';
import 'breakpoints.dart';

/// A Widget that takes a mapping of [SlotLayoutConfig]s to [Breakpoint]s and
/// adds the appropriate Widget based on the current screen size.
///
/// See also:
/// * [AdaptiveLayout], where [SlotLayout]s are assigned to placements on the
///   screen called "slots".
class SlotLayout extends StatefulWidget {
  /// Creates a [SlotLayout] widget.
  const SlotLayout({required this.config, super.key});

  /// Given a context and a config, it returns the [SlotLayoutConfig] that will g
  /// be chosen from the config under the context's conditions.
  static SlotLayoutConfig? pickWidget(
      BuildContext context, Map<Breakpoint, SlotLayoutConfig?> config) {
    SlotLayoutConfig? chosenWidget;
    config.forEach((Breakpoint breakpoint, SlotLayoutConfig? pickedWidget) {
      if (breakpoint.isActive(context)) {
        chosenWidget = pickedWidget;
      }
    });
    return chosenWidget;
  }

  /// Maps [Breakpoint]s to [SlotLayoutConfig]s to determine what Widget to
  /// display on which condition of screens.
  ///
  /// The [SlotLayoutConfig]s in this map are nullable since some breakpoints
  /// apply to more open ranges and the nullability allows one to override the
  /// value at that Breakpoint to be null.
  ///
  /// [SlotLayout] picks the last [SlotLayoutConfig] whose corresponding
  /// [Breakpoint.isActive] returns true.
  ///
  /// If two [Breakpoint]s are active concurrently then the latter one defined
  /// in the map takes priority.
  final Map<Breakpoint, SlotLayoutConfig?> config;

  /// A wrapper for the children passed to [SlotLayout] to provide appropriate
  /// config information.
  ///
  /// Acts as a delegate to the abstract class [SlotLayoutConfig].
  /// It first takes a builder which returns the child Widget that [SlotLayout]
  /// eventually displays with an animation.
  ///
  /// It also takes an inAnimation and outAnimation to describe how the Widget
  /// should be animated as it is switched in or out from [SlotLayout]. These
  /// are both defined as functions that takes a [Widget] and an [Animation] and
  /// return a [Widget]. These functions are passed to the [AnimatedSwitcher]
  /// inside [SlotLayout] and are to be played when the child enters/exits.
  ///
  /// Last, it takes a required key. The key should be kept constant but unique
  /// as this key is what is used to let the [SlotLayout] know that a change has
  /// been made to its child.
  ///
  /// If you define a given animation phase, there may be multiple
  /// widgets being displayed depending on the phases you have chosen to animate.
  /// If you are using GlobalKeys, this may cause issues with the
  /// [AnimatedSwitcher].
  ///
  /// See also:
  ///
  ///  * [AnimatedWidget] and [ImplicitlyAnimatedWidget], which are commonly used
  ///   as the returned widget for the inAnimation and outAnimation functions.
  ///  * [AnimatedSwitcher.defaultTransitionBuilder], which is what takes the
  ///   inAnimation and outAnimation.
  static SlotLayoutConfig from({
    WidgetBuilder? builder,
    Widget Function(Widget, Animation<double>)? inAnimation,
    Widget Function(Widget, Animation<double>)? outAnimation,
    required Key key,
  }) =>
      SlotLayoutConfig._(
        builder: builder,
        inAnimation: inAnimation,
        outAnimation: outAnimation,
        key: key,
      );

  @override
  State<SlotLayout> createState() => _SlotLayoutState();
}

class _SlotLayoutState extends State<SlotLayout>
    with SingleTickerProviderStateMixin {
  SlotLayoutConfig? chosenWidget;

  @override
  Widget build(BuildContext context) {
    chosenWidget = SlotLayout.pickWidget(context, widget.config);
    bool hasAnimation = false;
    return AnimatedSwitcher(
        duration: const Duration(milliseconds: 1000),
        layoutBuilder: (Widget? currentChild, List<Widget> previousChildren) {
          final Stack elements = Stack(
            children: <Widget>[
              if (hasAnimation && previousChildren.isNotEmpty)
                previousChildren.first,
              if (currentChild != null) currentChild,
            ],
          );
          return elements;
        },
        transitionBuilder: (Widget child, Animation<double> animation) {
          final SlotLayoutConfig configChild = child as SlotLayoutConfig;
          if (child.key == chosenWidget?.key) {
            return (configChild.inAnimation != null)
                ? child.inAnimation!(child, animation)
                : child;
          } else {
            if (configChild.outAnimation != null) {
              hasAnimation = true;
            }
            return (configChild.outAnimation != null)
                ? child.outAnimation!(child, ReverseAnimation(animation))
                : child;
          }
        },
        child: chosenWidget ?? SlotLayoutConfig.empty());
  }
}

/// Defines how [SlotLayout] should display under a certain [Breakpoint].
class SlotLayoutConfig extends StatelessWidget {
  /// Creates a new [SlotLayoutConfig].
  ///
  /// Returns the child widget as is but holds properties to be accessed by other
  /// classes.
  const SlotLayoutConfig._({
    super.key,
    required this.builder,
    this.inAnimation,
    this.outAnimation,
  });

  /// The child Widget that [SlotLayout] eventually returns with an animation.
  final WidgetBuilder? builder;

  /// A function that provides the animation to be wrapped around the builder
  /// child as it is being moved in during a switch in [SlotLayout].
  ///
  /// See also:
  ///
  ///  * [AnimatedWidget] and [ImplicitlyAnimatedWidget], which are commonly used
  ///   as the returned widget.
  final Widget Function(Widget, Animation<double>)? inAnimation;

  /// A function that provides the animation to be wrapped around the builder
  /// child as it is being moved in during a switch in [SlotLayout].
  ///
  /// See also:
  ///
  ///  * [AnimatedWidget] and [ImplicitlyAnimatedWidget], which are commonly used
  ///   as the returned widget.
  final Widget Function(Widget, Animation<double>)? outAnimation;

  /// An empty [SlotLayoutConfig] to be placed in a slot to indicate that the slot
  /// should show nothing.
  static SlotLayoutConfig empty() {
    return const SlotLayoutConfig._(key: Key(''), builder: null);
  }

  @override
  Widget build(BuildContext context) {
    return (builder != null) ? builder!(context) : const SizedBox.shrink();
  }
}
