import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_sound/public/flutter_sound_recorder.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:lba/gen/assets.gen.dart';
import 'package:lba/res/colors.dart';
import 'package:lba/widgets/chat_text_input_field.dart';
import 'package:lba/widgets/recorded_audio_preview.dart';
import 'package:lba/widgets/recording_indicator.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:vibration/vibration.dart';

class Planner extends StatefulWidget {
  const Planner({super.key});

  @override
  State<Planner> createState() => _PlannerState();
}

class _PlannerState extends State<Planner> with TickerProviderStateMixin {
  final ImagePicker _picker = ImagePicker();
  final GlobalKey _attachIconKey = GlobalKey();
  final TextEditingController _textController = TextEditingController();

  bool _isLoading = false;
  String _sentText = "";
  XFile? _sentImage;
  String? _sentAudioPath;
  Duration _sentAudioDuration = Duration.zero;

  XFile? _attachedImage;

  FlutterSoundRecorder? _audioRecorder;
  bool _isRecording = false;
  String? _recordedAudioPath;
  Duration _recordDuration = Duration.zero;
  Timer? _recordingTimer;

  late AnimationController _micPulseController;
  late Animation<double> _micPulseAnimation;
  late AnimationController _pageEnterController;
  late Animation<double> _staggeredAnimation;
  late Animation<Offset> _textInputAnimation;

  final List<String> suggestions = [
    'running shoes',
    'hotel',
    'power tools',
    'food',
    'cafe',
    'fashion',
    'gift',
    'indoor plants',
  ];

  @override
  void initState() {
    super.initState();
    _initRecorder();

    _micPulseController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1000),
    )..repeat(reverse: true);
    _micPulseAnimation = Tween<double>(
      begin: 1.0,
      end: 1.4,
    ).animate(_micPulseController);

    _pageEnterController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1200),
    );

    _staggeredAnimation = CurvedAnimation(
      parent: _pageEnterController,
      curve: Curves.easeOutCubic,
    );

    _textInputAnimation = Tween<Offset>(
      begin: const Offset(0, 1),
      end: Offset.zero,
    ).animate(
      CurvedAnimation(
        parent: _pageEnterController,
        curve: const Interval(0.4, 1.0, curve: Curves.easeOutCubic),
      ),
    );

    _pageEnterController.forward();
  }

  Future<void> _initRecorder() async {
    try {
      _audioRecorder = FlutterSoundRecorder();
      await _audioRecorder!.openRecorder();
    } catch (e) {
      debugPrint('Error initializing recorder: $e');
    }
  }

  @override
  void dispose() {
    _textController.dispose();
    _audioRecorder?.closeRecorder();
    _recordingTimer?.cancel();
    _micPulseController.dispose();
    _pageEnterController.dispose();
    super.dispose();
  }

  void _showAttachmentOptions() {
    final RenderBox renderBox =
        _attachIconKey.currentContext!.findRenderObject() as RenderBox;
    final position = renderBox.localToGlobal(Offset.zero);

    const double menuWidth = 220.0;
    const double menuHeight = 120.0;

    showGeneralDialog(
      context: context,
      barrierDismissible: true,
      barrierLabel: 'Attachment Options',
      barrierColor: Colors.black.withOpacity(0.1),
      transitionDuration: const Duration(milliseconds: 200),
      pageBuilder: (context, anim1, anim2) {
        return GestureDetector(
          onTap: () => Navigator.of(context).pop(),
          child: Material(
            color: Colors.transparent,
            child: Stack(
              children: [
                Positioned(
                  left: position.dx + 30,
                  top: position.dy - menuHeight + 5,
                  child: GestureDetector(
                    onTap: () {},
                    child: PopupMenuWithoutTail(
                      child: SizedBox(
                        width: menuWidth,
                        height: menuHeight,
                        child: _buildAttachmentMenuContent(),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
      transitionBuilder: (context, animation, secondaryAnimation, child) {
        return FadeTransition(
          opacity: CurvedAnimation(parent: animation, curve: Curves.easeOut),
          child: child,
        );
      },
    );
  }

  Widget _buildAttachmentMenuContent() {
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        ListTile(
          leading: SvgPicture.asset(Assets.icons.camera2.path, height: 20),
          title: const Text('Snap a photo', style: TextStyle(fontSize: 16)),
          onTap: () {
            Navigator.of(context).pop();
            _pickImage(ImageSource.camera);
          },
          dense: true,
        ),
        const Divider(thickness: 0.5, height: 1, indent: 55, endIndent: 55),
        ListTile(
          leading: SvgPicture.asset(Assets.icons.galleryAdd.path, height: 19),
          title: const Text('Upload a photo', style: TextStyle(fontSize: 16)),
          onTap: () {
            Navigator.of(context).pop();
            _pickImage(ImageSource.gallery);
          },
          dense: true,
        ),
      ],
    );
  }

  Future<void> _pickImage(ImageSource source) async {
    try {
      final XFile? pickedFile = await _picker.pickImage(source: source);
      if (pickedFile != null) {
        setState(() {
          _attachedImage = pickedFile;
        });
      }
    } catch (e) {
      debugPrint("Error picking image: $e");
    }
  }

  void _removeAttachedImage() {
    setState(() {
      _attachedImage = null;
    });
  }

  void _sendMessage() {
    final text = _textController.text.trim();
    final imageFile = _attachedImage;
    final audioPath = _recordedAudioPath;

    if (text.isNotEmpty || imageFile != null || audioPath != null) {
      setState(() {
        _isLoading = true;
        _sentText = text;
        _sentImage = imageFile;
        _sentAudioPath = audioPath;
        _sentAudioDuration = _recordDuration;
        _textController.clear();
        _attachedImage = null;
        _recordedAudioPath = null;
        _recordDuration = Duration.zero;
      });

      Future.delayed(const Duration(seconds: 3), () {
        if (mounted) {
          setState(() {
            _isLoading = false;
          });
        }
      });
    }
  }

  Future<void> _startRecording() async {
    final permission = await Permission.microphone.request();
    if (permission != PermissionStatus.granted) return;

    try {
      if (await Vibration.hasVibrator() ?? false) {
        Vibration.vibrate(duration: 100);
      }
      final Directory tempDir = await getTemporaryDirectory();
      final String filePath =
          '${tempDir.path}/recording_${DateTime.now().millisecondsSinceEpoch}.aac';

      await _audioRecorder!.startRecorder(
        toFile: filePath,
        codec: Codec.aacADTS,
      );
      setState(() {
        _isRecording = true;
        _recordDuration = Duration.zero;
      });
      _startRecordTimer();
    } catch (e) {
      debugPrint('Error starting recording: $e');
    }
  }

  Future<void> _stopRecording() async {
    if (!_isRecording) return;
    try {
      _recordingTimer?.cancel();
      final path = await _audioRecorder!.stopRecorder();
      setState(() {
        _isRecording = false;
        _recordedAudioPath = path;
      });
    } catch (e) {
      debugPrint('Error stopping recording: $e');
    }
  }

  void _startRecordTimer() {
    _recordingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() => _recordDuration += const Duration(seconds: 1));
    });
  }

  void _deleteRecording() => setState(() {
    _recordedAudioPath = null;
    _recordDuration = Duration.zero;
  });

  String _formatDuration(Duration duration) {
    String twoDigits(int n) => n.toString().padLeft(2, "0");
    String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
    return "$twoDigitMinutes:$twoDigitSeconds";
  }

  Widget _buildAnimatedSection(
    Widget child, {
    required double begin,
    required double end,
  }) {
    return FadeTransition(
      opacity: CurvedAnimation(
        parent: _staggeredAnimation,
        curve: Interval(begin, end),
      ),
      child: SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0.0, 0.5),
          end: Offset.zero,
        ).animate(
          CurvedAnimation(
            parent: _staggeredAnimation,
            curve: Interval(begin, end),
          ),
        ),
        child: child,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.scaffoldBackground,
      appBar: AppBar(
        backgroundColor: AppColors.scaffoldBackground,
        elevation: 1,
        shadowColor: AppColors.divider.withOpacity(0.2),
        surfaceTintColor: Colors.transparent,
        title: Text(
          'Smart Planner',
          style: TextStyle(
            color: AppColors.textPrimary,
            fontSize: 18,
            fontWeight: FontWeight.normal,
          ),
        ),
        actions: [
          IconButton(
            icon: SvgPicture.asset(
              Assets.icons.mDSPublicTWButton1.path,
              color: AppColors.isDarkMode ? Colors.white : null,
            ),
            onPressed: () {},
          ),
        ],
      ),
      body: Column(
        children: [
          Expanded(
            child: AnimatedSwitcher(
              duration: const Duration(milliseconds: 500),
              transitionBuilder: (child, animation) {
                return FadeTransition(
                  opacity: animation,
                  child: ScaleTransition(
                    scale: Tween<double>(
                      begin: 0.9,
                      end: 1.0,
                    ).animate(animation),
                    child: child,
                  ),
                );
              },
              child: _isLoading ? _buildLoadingView() : _buildDefaultView(),
            ),
          ),
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            transitionBuilder: (child, animation) {
              return SizeTransition(
                sizeFactor: animation,
                child: FadeTransition(opacity: animation, child: child),
              );
            },
            child:
                _attachedImage != null
                    ? _buildAttachedImagePreview()
                    : const SizedBox.shrink(),
          ),
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            transitionBuilder: (child, animation) {
              return SizeTransition(
                sizeFactor: animation,
                child: FadeTransition(opacity: animation, child: child),
              );
            },
            child:
                _recordedAudioPath != null
                    ? RecordedAudioPreview(
                      audioPath: _recordedAudioPath!,
                      totalDuration: _recordDuration,
                      onDelete: _deleteRecording,
                      formatDuration: _formatDuration,
                    )
                    : const SizedBox.shrink(),
          ),
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            transitionBuilder: (child, animation) {
              return SizeTransition(
                sizeFactor: animation,
                child: FadeTransition(opacity: animation, child: child),
              );
            },
            child:
                _isRecording
                    ? RecordingIndicator(
                      formattedDuration: _formatDuration(_recordDuration),
                    )
                    : const SizedBox.shrink(),
          ),
          SlideTransition(
            position: _textInputAnimation,
            child: ChatTextInputField(
              textController: _textController,
              onSendMessage: _sendMessage,
              onShowAttachmentOptions: _showAttachmentOptions,
              onStartRecording: _startRecording,
              onStopRecording: _stopRecording,
              isRecording: _isRecording,
              micPulseAnimation: _micPulseAnimation,
              attachIconKey: _attachIconKey,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildDefaultView() {
    return ListView(
      key: const ValueKey('default'),
      padding: const EdgeInsets.all(16.0),
      children: [
        _buildAnimatedSection(
          _buildChatBubble(
            icon: Assets.icons.flatColorIconsPlanner.path,
            text:
                "\"Hi there! Tell me what you need – I'm here to plan it for you!\" ",
            backgroundColor: AppColors.nearbyPopup,
            iconBackgroundColor: Colors.transparent,
          ),
          begin: 0.0,
          end: 0.5,
        ),
        const SizedBox(height: 16),
        _buildAnimatedSection(
          _buildSuggestionArea(suggestions),
          begin: 0.2,
          end: 1.0,
        ),
      ],
    );
  }

  Widget _buildLoadingView() {
    return Padding(
      key: const ValueKey('loading'),
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Column(
        children: [
          _buildUserRequestBubble(),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 15.0),
            child: Divider(color: Color.fromARGB(255, 224, 224, 224)),
          ),
          Text(
            "\"Scanning the best deals just for you...\"",
            textAlign: TextAlign.center,
            style: TextStyle(
              fontSize: 15,
              color: AppColors.hintTitle,
              height: 1.4,
            ),
          ),
          const SizedBox(height: 12),
          const SlantedLinesAnimation(isLoading: true),
        ],
      ),
    );
  }

  Widget _buildUserRequestBubble() {
    bool hasImage = _sentImage != null;
    bool hasText = _sentText.isNotEmpty;
    bool hasAudio = _sentAudioPath != null;

    if (hasImage || hasAudio) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if (hasImage)
            Center(
              child: Padding(
                padding: const EdgeInsets.only(top: 0.0, right: 12.0),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(12.0),
                  child: Image.file(
                    File(_sentImage!.path),
                    width: 75,
                    height: 75,
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            ),
          if (hasAudio && !hasImage)
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: AppColors.nearbyPopup,
                borderRadius: BorderRadius.circular(16),
                border: Border.all(color: AppColors.primary.withOpacity(0.3)),
              ),
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Container(
                    width: 32,
                    height: 32,
                    decoration: BoxDecoration(
                      color: AppColors.primary,
                      shape: BoxShape.circle,
                    ),
                    child: const Icon(
                      Icons.volume_up,
                      color: Colors.white,
                      size: 16,
                    ),
                  ),
                  const SizedBox(width: 8),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text(
                        'Voice Message',
                        style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.w500,
                          color: AppColors.textSecondary,
                        ),
                      ),
                      Text(
                        _formatDuration(_sentAudioDuration),
                        style: TextStyle(
                          fontSize: 10,
                          color: AppColors.textSecondary,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          if (hasText)
            Flexible(
              child: Container(
                padding: const EdgeInsets.symmetric(
                  vertical: 6,
                  horizontal: 16,
                ),
                decoration: BoxDecoration(
                  color: AppColors.nearbyPopup,
                  borderRadius: BorderRadius.circular(16),
                  border: Border.all(color: AppColors.divider),
                ),
                child: Text(
                  "\"$_sentText\"",
                  style: TextStyle(
                    fontSize: 15,
                    color: AppColors.hintTitle,
                    height: 1.4,
                  ),
                ),
              ),
            ),
        ],
      );
    } else {
      return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Flexible(
            child: IntrinsicHeight(
              child: Container(
                decoration: BoxDecoration(
                  color: AppColors.nearbyPopup,
                  borderRadius: BorderRadius.circular(16),
                  border: Border.all(color: AppColors.divider),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Flexible(
                      child: Padding(
                        padding: const EdgeInsets.symmetric(
                          vertical: 6,
                          horizontal: 16,
                        ),
                        child: Text(
                          "\"$_sentText\"",
                          style: TextStyle(
                            fontSize: 15,
                            color: AppColors.hintTitle,
                            height: 1.4,
                          ),
                        ),
                      ),
                    ),
                    Container(
                      width: 10,
                      decoration: BoxDecoration(
                        color: AppColors.primary,
                        borderRadius: BorderRadius.only(
                          topRight: Radius.circular(16),
                          bottomRight: Radius.circular(16),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      );
    }
  }

  Widget _buildAttachedImagePreview() {
    return Padding(
      key: const ValueKey('image_preview'),
      padding: const EdgeInsets.fromLTRB(35, 8, 16, 0),
      child: Align(
        alignment: Alignment.centerLeft,
        child: SizedBox(
          height: 120,
          width: 120,
          child: Stack(
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(16.0),
                child: Image.file(
                  File(_attachedImage!.path),
                  height: 120,
                  width: 120,
                  fit: BoxFit.cover,
                ),
              ),
              Positioned(
                top: 6,
                left: 6,
                child: GestureDetector(
                  onTap: _removeAttachedImage,
                  child: Container(
                    decoration: BoxDecoration(
                      color: AppColors.surface.withOpacity(0.6),
                      shape: BoxShape.circle,
                    ),
                    padding: const EdgeInsets.all(4),
                    child: Icon(
                      Icons.close,
                      color: AppColors.textPrimary,
                      size: 18,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildChatBubble({
    required String icon,
    required String text,
    required Color backgroundColor,
    required Color iconBackgroundColor,
  }) {
    return Container(
      padding: const EdgeInsets.all(12.0),
      decoration: BoxDecoration(
        color: backgroundColor,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            padding: const EdgeInsets.all(8),
            decoration: BoxDecoration(
              color: iconBackgroundColor,
              borderRadius: BorderRadius.circular(10),
            ),
            child: SvgPicture.asset(icon, height: 24),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.only(top: 2.0),
              child: Text(
                text,
                style: TextStyle(
                  fontSize: 15,
                  color: AppColors.hintTitle,
                  height: 1.4,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSuggestionArea(List<String> suggestions) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 16.0),
      decoration: BoxDecoration(
        color: AppColors.cardBackground,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.only(top: 2.0),
            child: SvgPicture.asset(Assets.icons.flatColorIconsIdea.path),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  "\"Need help? Here are some ideas you can ask me about!\"",
                  style: TextStyle(
                    fontSize: 15,
                    color: AppColors.hintTitle,
                    height: 1.4,
                  ),
                ),
                const SizedBox(height: 16),
                Wrap(
                  spacing: 10.0,
                  runSpacing: 10.0,
                  alignment: WrapAlignment.start,
                  children:
                      suggestions.asMap().entries.map((entry) {
                        final index = entry.key;
                        final suggestion = entry.value;
                        return FadeTransition(
                          opacity: CurvedAnimation(
                            parent: _staggeredAnimation,
                            curve: Interval(0.4 + (index * 0.05), 1.0),
                          ),
                          child: SlideTransition(
                            position: Tween<Offset>(
                              begin: const Offset(0.2, 0.0),
                              end: Offset.zero,
                            ).animate(
                              CurvedAnimation(
                                parent: _staggeredAnimation,
                                curve: Interval(0.4 + (index * 0.05), 1.0),
                              ),
                            ),
                            child: _buildSuggestionChip(suggestion),
                          ),
                        );
                      }).toList(),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSuggestionChip(String text) {
    return GestureDetector(
      onTap: () {
        _textController.text = text;
        _textController.selection = TextSelection.fromPosition(
          TextPosition(offset: _textController.text.length),
        );
      },
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20),
          border: Border.all(color: AppColors.primary, width: 1),
        ),
        child: Text(
          text,
          style: TextStyle(
            color: AppColors.textSecondary,
            fontWeight: FontWeight.w500,
            fontSize: 14,
          ),
        ),
      ),
    );
  }
}

class SlantedLinesAnimation extends StatefulWidget {
  final bool isLoading;
  const SlantedLinesAnimation({super.key, this.isLoading = false});

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

class _SlantedLinesAnimationState extends State<SlantedLinesAnimation>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    )..repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return ClipRRect(
          borderRadius: BorderRadius.circular(4),
          child: CustomPaint(
            painter: _SlantedLinesPainter(_controller.value),
            child: const SizedBox(height: 8, width: 180),
          ),
        );
      },
    );
  }
}

class _SlantedLinesPainter extends CustomPainter {
  final double progress;
  _SlantedLinesPainter(this.progress);

  @override
  void paint(Canvas canvas, Size size) {
    const double stripeWidth = 5.0;
    const double angle = -0.5;

    final Paint paint =
        Paint()
          ..shader = LinearGradient(
            colors: [AppColors.primary, AppColors.loadingBorder],
            stops: const [0.5, 0.5],
            tileMode: TileMode.repeated,
            transform: GradientRotation(angle),
          ).createShader(
            Rect.fromLTWH(
              -progress * stripeWidth * 4,
              0,
              stripeWidth * 4,
              size.height,
            ),
          );

    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint);
  }

  @override
  bool shouldRepaint(covariant _SlantedLinesPainter oldDelegate) {
    return oldDelegate.progress != progress;
  }
}

class PopupMenuWithoutTail extends StatelessWidget {
  final Widget child;
  const PopupMenuWithoutTail({super.key, required this.child});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _MenuPainter(
        color: AppColors.surface,
        shadowColor: Colors.black.withOpacity(0.15),
      ),
      child: child,
    );
  }
}

class _MenuPainter extends CustomPainter {
  final Color color;
  final Color shadowColor;
  final double radius = 20.0;

  _MenuPainter({required this.color, required this.shadowColor});

  @override
  void paint(Canvas canvas, Size size) {
    final paint =
        Paint()
          ..color = color
          ..style = PaintingStyle.fill;

    final path =
        Path()
          ..moveTo(radius, 0)
          ..lineTo(size.width - radius, 0)
          ..arcToPoint(
            Offset(size.width, radius),
            radius: Radius.circular(radius),
          )
          ..lineTo(size.width, size.height - radius)
          ..arcToPoint(
            Offset(size.width - radius, size.height),
            radius: Radius.circular(radius),
          )
          ..lineTo(0, size.height)
          ..lineTo(0, radius)
          ..arcToPoint(Offset(radius, 0), radius: Radius.circular(radius))
          ..close();

    canvas.drawShadow(path, shadowColor, 10.0, true);
    canvas.drawPath(path, paint);
  }

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