// Copyright 2014 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 'dart:math' as math;

import 'package:flutter/material.dart';

const double _kFrontHeadingHeight = 32.0; // front layer beveled rectangle
const double _kFrontClosedHeight = 92.0; // front layer height when closed
const double _kBackAppBarHeight = 56.0; // back layer (options) appbar height

// The size of the front layer heading's left and right beveled corners.
final Animatable<BorderRadius?> _kFrontHeadingBevelRadius = BorderRadiusTween(
  begin: const BorderRadius.only(
    topLeft: Radius.circular(12.0),
    topRight: Radius.circular(12.0),
  ),
  end: const BorderRadius.only(
    topLeft: Radius.circular(_kFrontHeadingHeight),
    topRight: Radius.circular(_kFrontHeadingHeight),
  ),
);

class _TappableWhileStatusIs extends StatefulWidget {
  const _TappableWhileStatusIs(
    this.status, {
    this.controller,
    this.child,
  });

  final AnimationController? controller;
  final AnimationStatus status;
  final Widget? child;

  @override
  _TappableWhileStatusIsState createState() => _TappableWhileStatusIsState();
}

class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
  bool? _active;

  @override
  void initState() {
    super.initState();
    widget.controller!.addStatusListener(_handleStatusChange);
    _active = widget.controller!.status == widget.status;
  }

  @override
  void dispose() {
    widget.controller!.removeStatusListener(_handleStatusChange);
    super.dispose();
  }

  void _handleStatusChange(AnimationStatus status) {
    final bool value = widget.controller!.status == widget.status;
    if (_active != value) {
      setState(() {
        _active = value;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget child = AbsorbPointer(
      absorbing: !_active!,
      child: widget.child,
    );

    if (!_active!) {
      child = FocusScope(
        canRequestFocus: false,
        debugLabel: '$_TappableWhileStatusIs',
        child: child,
      );
    }
    return child;
  }
}

class _CrossFadeTransition extends AnimatedWidget {
  const _CrossFadeTransition({
    this.alignment = Alignment.center,
    required Animation<double> progress,
    this.child0,
    this.child1,
  }) : super(listenable: progress);

  final AlignmentGeometry alignment;
  final Widget? child0;
  final Widget? child1;

  @override
  Widget build(BuildContext context) {
    final Animation<double> progress = listenable as Animation<double>;

    final double opacity1 = CurvedAnimation(
      parent: ReverseAnimation(progress),
      curve: const Interval(0.5, 1.0),
    ).value;

    final double opacity2 = CurvedAnimation(
      parent: progress,
      curve: const Interval(0.5, 1.0),
    ).value;

    return Stack(
      alignment: alignment,
      children: <Widget>[
        Opacity(
          opacity: opacity1,
          child: Semantics(
            scopesRoute: true,
            explicitChildNodes: true,
            child: child1,
          ),
        ),
        Opacity(
          opacity: opacity2,
          child: Semantics(
            scopesRoute: true,
            explicitChildNodes: true,
            child: child0,
          ),
        ),
      ],
    );
  }
}

class _BackAppBar extends StatelessWidget {
  const _BackAppBar({
    this.leading = const SizedBox(width: 56.0),
    required this.title,
    this.trailing,
  });

  final Widget leading;
  final Widget title;
  final Widget? trailing;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return IconTheme.merge(
      data: theme.primaryIconTheme,
      child: DefaultTextStyle(
        style: theme.primaryTextTheme.titleLarge!,
        child: SizedBox(
          height: _kBackAppBarHeight,
          child: Row(
            children: <Widget>[
              Container(
                alignment: Alignment.center,
                width: 56.0,
                child: leading,
              ),
              Expanded(
                child: title,
              ),
              if (trailing != null)
                Container(
                  alignment: Alignment.center,
                  width: 56.0,
                  child: trailing,
                ),
            ],
          ),
        ),
      ),
    );
  }
}

class Backdrop extends StatefulWidget {
  const Backdrop({
    super.key,
    this.frontAction,
    this.frontTitle,
    this.frontHeading,
    this.frontLayer,
    this.backTitle,
    this.backLayer,
  });

  final Widget? frontAction;
  final Widget? frontTitle;
  final Widget? frontLayer;
  final Widget? frontHeading;
  final Widget? backTitle;
  final Widget? backLayer;

  @override
  State<Backdrop> createState() => _BackdropState();
}

class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin {
  final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');
  AnimationController? _controller;
  late Animation<double> _frontOpacity;

  static final Animatable<double> _frontOpacityTween = Tween<double>(begin: 0.2, end: 1.0)
    .chain(CurveTween(curve: const Interval(0.0, 0.4, curve: Curves.easeInOut)));

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      value: 1.0,
      vsync: this,
    );
    _controller!.addStatusListener((AnimationStatus status) {
      setState(() {
        // This is intentionally left empty. The state change itself takes
        // place inside the AnimationController, so there's nothing to update.
        // All we want is for the widget to rebuild and read the new animation
        // state from the AnimationController.
      });
    });
    _frontOpacity = _controller!.drive(_frontOpacityTween);
  }

  @override
  void dispose() {
    _controller!.dispose();
    super.dispose();
  }

  double get _backdropHeight {
    // Warning: this can be safely called from the event handlers but it may
    // not be called at build time.
    final RenderBox renderBox = _backdropKey.currentContext!.findRenderObject()! as RenderBox;
    return math.max(0.0, renderBox.size.height - _kBackAppBarHeight - _kFrontClosedHeight);
  }

  void _handleDragUpdate(DragUpdateDetails details) {
    _controller!.value -= details.primaryDelta! / _backdropHeight;
  }

  void _handleDragEnd(DragEndDetails details) {
    if (_controller!.isAnimating || _controller!.status == AnimationStatus.completed) {
      return;
    }

    final double flingVelocity = details.velocity.pixelsPerSecond.dy / _backdropHeight;
    if (flingVelocity < 0.0) {
      _controller!.fling(velocity: math.max(2.0, -flingVelocity));
    } else if (flingVelocity > 0.0) {
      _controller!.fling(velocity: math.min(-2.0, -flingVelocity));
    } else {
      _controller!.fling(velocity: _controller!.value < 0.5 ? -2.0 : 2.0);
    }
  }

  void _toggleFrontLayer() {
    final AnimationStatus status = _controller!.status;
    final bool isOpen = status == AnimationStatus.completed || status == AnimationStatus.forward;
    _controller!.fling(velocity: isOpen ? -2.0 : 2.0);
  }

  Widget _buildStack(BuildContext context, BoxConstraints constraints) {
    final Animation<RelativeRect> frontRelativeRect = _controller!.drive(RelativeRectTween(
      begin: RelativeRect.fromLTRB(0.0, constraints.biggest.height - _kFrontClosedHeight, 0.0, 0.0),
      end: const RelativeRect.fromLTRB(0.0, _kBackAppBarHeight, 0.0, 0.0),
    ));
    return Stack(
      key: _backdropKey,
      children: <Widget>[
        // Back layer
        Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            _BackAppBar(
              leading: widget.frontAction!,
              title: _CrossFadeTransition(
                progress: _controller!,
                alignment: AlignmentDirectional.centerStart,
                child0: Semantics(namesRoute: true, child: widget.frontTitle),
                child1: Semantics(namesRoute: true, child: widget.backTitle),
              ),
              trailing: IconButton(
                onPressed: _toggleFrontLayer,
                tooltip: 'Toggle options page',
                icon: AnimatedIcon(
                  icon: AnimatedIcons.close_menu,
                  progress: _controller!,
                ),
              ),
            ),
            Expanded(
              child: _TappableWhileStatusIs(
                AnimationStatus.dismissed,
                controller: _controller,
                child: Visibility(
                  visible: _controller!.status != AnimationStatus.completed,
                  maintainState: true,
                  child: widget.backLayer!,
                ),
              ),
            ),
          ],
        ),
        // Front layer
        PositionedTransition(
          rect: frontRelativeRect,
          child: AnimatedBuilder(
            animation: _controller!,
            builder: (BuildContext context, Widget? child) {
              return PhysicalShape(
                elevation: 12.0,
                color: Theme.of(context).canvasColor,
                clipper: ShapeBorderClipper(
                  shape: BeveledRectangleBorder(
                    borderRadius: _kFrontHeadingBevelRadius.transform(_controller!.value)!,
                  ),
                ),
                clipBehavior: Clip.antiAlias,
                child: child,
              );
            },
            child: _TappableWhileStatusIs(
              AnimationStatus.completed,
              controller: _controller,
              child: FadeTransition(
                opacity: _frontOpacity,
                child: widget.frontLayer,
              ),
            ),
          ),
        ),
        // The front "heading" is a (typically transparent) widget that's stacked on
        // top of, and at the top of, the front layer. It adds support for dragging
        // the front layer up and down and for opening and closing the front layer
        // with a tap. It may obscure part of the front layer's topmost child.
        if (widget.frontHeading != null)
          PositionedTransition(
            rect: frontRelativeRect,
            child: ExcludeSemantics(
              child: Container(
                alignment: Alignment.topLeft,
                child: GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onTap: _toggleFrontLayer,
                  onVerticalDragUpdate: _handleDragUpdate,
                  onVerticalDragEnd: _handleDragEnd,
                  child: widget.frontHeading,
                ),
              ),
            ),
          ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: _buildStack);
  }
}
