import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';

import 'package:reversi/utils/color_extensions.dart';

class StyledButton extends StatelessWidget {
  const StyledButton({
    super.key,
    required this.color,
    required this.onPressed,
    this.onLongPress,
    required this.child,
  });

  final Color color;
  final VoidCallback? onPressed;
  final VoidCallback? onLongPress;
  final Widget child;

  factory StyledButton.text({
    Key? key,
    required VoidCallback? onPressed,
    VoidCallback? onLongPress,
    required String caption,
    required Color color,
  }) {
    final Widget captionWidget = AutoSizeText(
      caption,
      maxLines: 1,
      style: TextStyle(
        inherit: true,
        fontWeight: FontWeight.w900,
        color: color.darken(60),
        shadows: [
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(2, 2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(2, -2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(-2, 2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(-2, -2),
          ),
        ],
      ),
    );

    return StyledButton(
      color: color,
      onPressed: onPressed,
      onLongPress: onLongPress,
      child: captionWidget,
    );
  }

  factory StyledButton.icon({
    Key? key,
    required VoidCallback? onPressed,
    VoidCallback? onLongPress,
    required Icon icon,
    required Color color,
    required double iconSize,
  }) {
    return StyledButton(
      color: color,
      onPressed: onPressed,
      onLongPress: onLongPress,
      child: Icon(
        icon.icon,
        color: icon.color ?? color.darken(60),
        size: iconSize,
        shadows: [
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(2, 2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(2, -2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(-2, 2),
          ),
          Shadow(
            blurRadius: 5.0,
            color: color.lighten(60),
            offset: const Offset(-2, -2),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    const double borderWidth = 4;
    final Color borderColor = color.darken(40);
    const double borderRadius = 10;

    return Container(
      margin: const EdgeInsets.all(2),
      padding: const EdgeInsets.all(2),
      decoration: BoxDecoration(
        color: color,
        border: Border.all(
          color: borderColor,
          width: borderWidth,
        ),
        borderRadius: BorderRadius.circular(borderRadius),
      ),
      child: CustomPaint(
        painter: StyledButtonPainter(
          baseColor: color,
        ),
        child: MaterialButton(
          onPressed: onPressed,
          onLongPress: onLongPress,
          padding: const EdgeInsets.all(8),
          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
          minWidth: 40,
          child: child,
        ),
      ),
    );
  }
}

class StyledButtonPainter extends CustomPainter {
  StyledButtonPainter({
    required this.baseColor,
  });

  final Color baseColor;

  @override
  void paint(Canvas canvas, Size size) {
    final Color lightColor = baseColor.lighten(20);
    final Color darkColor = baseColor.darken(20);

    final Paint paint = Paint()..style = PaintingStyle.fill;

    const double cornerRadius = 6;

    Path topPath = Path()
      ..moveTo(cornerRadius, 0)
      ..lineTo(size.width - cornerRadius, 0)
      ..arcToPoint(
        Offset(size.width, cornerRadius),
        radius: const Radius.circular(cornerRadius),
      )
      ..lineTo(size.width, size.height * .35)
      ..quadraticBezierTo(
        size.width * .4,
        size.height * .1,
        0,
        size.height * .3,
      )
      ..lineTo(0, cornerRadius)
      ..arcToPoint(
        const Offset(cornerRadius, 0),
        radius: const Radius.circular(cornerRadius),
      );

    Path bottomPath = Path()
      ..moveTo(cornerRadius, size.height)
      ..lineTo(size.width - cornerRadius, size.height)
      ..arcToPoint(
        Offset(size.width, size.height - cornerRadius),
        radius: const Radius.circular(cornerRadius),
        clockwise: false,
      )
      ..lineTo(size.width, size.height * .7)
      ..quadraticBezierTo(
        size.width * .6,
        size.height * .9,
        0,
        size.height * .7,
      )
      ..lineTo(0, size.height - cornerRadius)
      ..arcToPoint(
        Offset(cornerRadius, size.height),
        radius: const Radius.circular(cornerRadius),
        clockwise: false,
      );

    paint.color = lightColor;
    canvas.drawPath(topPath, paint);

    paint.color = darkColor;
    canvas.drawPath(bottomPath, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}