import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:shimmer_animation/shimmer_animation.dart';
import 'package:vibration/vibration.dart';

class SliderButton extends StatefulWidget {
  ///To make button more customizable add your child widget
  final Widget? child;

  ///Sets the radius of corners of a button.
  final double radius;

  ///Use it to define a height and width of widget.
  final double height;
  final double width;
  final double buttonSize;

  ///Use it to define a color of widget.
  final Color backgroundColor;
  final Color baseColor;
  final Color highlightedColor;
  final Color buttonColor;

  ///Change it to gave a label on a widget of your choice.
  final Text? label;

  ///Gives a alignment to a slidder icon.
  final Alignment alignLabel;
  final BoxShadow boxShadow;
  final Widget icon;
  final Function action;

  ///Make it false if you want to deactivate the shimmer effect.
  final bool shimmer;

  ///Make it false if you want maintain the widget in the tree.
  final bool dismissible;

  final bool vibrationFlag;

  ///The offset threshold the item has to be dragged in order to be considered
  ///dismissed e.g. if it is 0.4, then the item has to be dragged
  /// at least 40% towards one direction to be considered dismissed
  final double dismissThresholds;

  final bool disable;
  final bool isLtr;
  const SliderButton({
    super.key,
    required this.action,
    this.radius = 100,
    this.boxShadow = const BoxShadow(color: Colors.black, blurRadius: 4),
    this.child,
    this.isLtr = true,
    this.vibrationFlag = true,
    this.shimmer = true,
    this.height = 70,
    this.buttonSize = 60,
    this.width = 250,
    this.alignLabel = const Alignment(0.0, 0),
    this.backgroundColor = const Color(0xffe0e0e0),
    this.baseColor = Colors.black87,
    this.buttonColor = Colors.white,
    this.highlightedColor = Colors.white,
    this.label,
    this.icon = const Icon(
      Icons.power_settings_new,
      color: Colors.red,
      size: 30.0,
      semanticLabel: 'Text to announce in accessibility modes',
    ),
    this.dismissible = true,
    this.dismissThresholds = 1.0,
    this.disable = false,
  }) : assert(buttonSize <= height);

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

class SliderButtonState extends State<SliderButton> {
  bool? flag;
  Widget? _child;

  @override
  void initState() {
    super.initState();
    flag = true;
    _child = widget.child;
  }

  @override
  Widget build(BuildContext context) {
    return flag == true ? _control() : widget.dismissible == true ? Container() : Container(
      child: _control(),
    );
  }

  Widget _control() => Container(
    height: widget.height,
    width: widget.width,
    decoration: BoxDecoration(
      color: widget.disable ? Colors.grey.shade700 : Get.isDarkMode ? Colors.white12 : widget.backgroundColor,
      borderRadius: BorderRadius.circular(widget.radius),
    ),
    alignment: Alignment.centerLeft,
    child: Stack(alignment: Alignment.centerLeft, children: <Widget>[

      Container(
        alignment: widget.alignLabel,
        child: widget.shimmer && !widget.disable ? Shimmer(
          color: widget.highlightedColor,
          child: widget.label!,
        ) : widget.label,
      ),

      widget.disable ? Tooltip(
        verticalOffset: 50,
        message: 'Button is disabled',
        child: Container(
          width: widget.width - (widget.height),
          height: widget.height,
          alignment: widget.isLtr ? Alignment.centerLeft : Alignment.centerRight,
          padding: EdgeInsets.only(left: (widget.height - widget.buttonSize) / 2),
          child: _child ?? Container(
            height: widget.buttonSize, width: widget.buttonSize,
            decoration: BoxDecoration(
              boxShadow: [widget.boxShadow],
              color: Colors.grey,
              borderRadius: BorderRadius.circular(widget.radius),
            ),
            child: Center(child: widget.icon),
          ),
        ),
      ) : Dismissible(
        key: const Key("cancel"),
        direction: DismissDirection.startToEnd,
        dismissThresholds: {
          DismissDirection.startToEnd: widget.dismissThresholds
        },

        ///gives direction of swipping in argument.
        onDismissed: (dir) async {
          setState(() {
            if (widget.dismissible) {
              flag = false;
            } else {
              flag = !flag!;
            }
          });

          widget.action();
          if (widget.vibrationFlag &&
              (await Vibration.hasVibrator())) {
            try {
              Vibration.vibrate(duration: 200);
            } catch (e) {
              if (kDebugMode) {
                print(e);
              }
            }
          }
        },
        child: Container(
          width: widget.width - (widget.height), height: widget.height,
          alignment: widget.isLtr ? Alignment.centerLeft : Alignment.centerRight,
          padding: EdgeInsets.only(left: (widget.height - widget.buttonSize) / 2),
          child: _child ?? Container(
            height: widget.buttonSize, width: widget.buttonSize,
            decoration: BoxDecoration(
              boxShadow: [widget.boxShadow],
              color: widget.buttonColor,
              borderRadius: BorderRadius.circular(widget.radius),
            ),
            child: Center(child: widget.icon),
          ),
        ),
      ),
      const SizedBox.expand(),
    ]),
  );
}