import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:frontend_eccp_mobile/app/core/constants/app_colors.dart';
import 'package:frontend_eccp_mobile/app/core/constants/enum/snackbar_type_enum.dart';

void showMessage(
  BuildContext context,
  String message,
  SnackBarType snackBarType, {
  int duration = 2000,
}) {
  final overlay = Overlay.of(context);

  final indicatorColor = switch (snackBarType) {
    SnackBarType.error => AppColors.primary900,
    SnackBarType.success => AppColors.statusSuccess,
    SnackBarType.warning => AppColors.statusWarning,
    _ => const Color(0xFF7FAAF6),
  };

  late OverlayEntry entry;

  entry = OverlayEntry(
    builder: (_) => _TopSnackBar(
      message: message,
      duration: duration,
      indicatorColor: indicatorColor,
      onDismiss: () {
        entry.remove();
      },
    ),
  );

  overlay.insert(entry);
}

class _TopSnackBar extends StatefulWidget {
  const _TopSnackBar({
    required this.message,
    required this.duration,
    required this.indicatorColor,
    required this.onDismiss,
  });

  final String message;
  final int duration;
  final Color indicatorColor;
  final VoidCallback onDismiss;

  @override
  State<_TopSnackBar> createState() => _TopSnackBarState();
}

class _TopSnackBarState extends State<_TopSnackBar>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;
  late Animation<Offset> slideAnimation;
  late Animation<double> opacityAnimation;

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

    controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 620),
      reverseDuration: const Duration(milliseconds: 520),
    );

    slideAnimation =
        Tween<Offset>(
          begin: const Offset(0, -2),
          end: Offset.zero,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeOutCubic,
            reverseCurve: Curves.easeInCubic,
          ),
        );

    opacityAnimation =
        Tween<double>(
          begin: 0,
          end: 1,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeOut,
          ),
        );

    unawaited(controller.forward());

    unawaited(_startTimer());
  }

  Future<void> _startTimer() async {
    await Future<void>.delayed(Duration(milliseconds: widget.duration));
    await dismiss();
  }

  Future<void> dismiss() async {
    if (!mounted) return;
    await controller.reverse();
    widget.onDismiss();
  }

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

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top: MediaQuery.of(context).padding.top + 8,
      left: 16.w,
      right: 16.w,
      child: SlideTransition(
        position: slideAnimation,
        child: FadeTransition(
          opacity: opacityAnimation,
          child: Material(
            color: Colors.transparent,
            child: GestureDetector(
              onTap: dismiss,
              child: Container(
                constraints: BoxConstraints(maxWidth: 600.w),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(8.r),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black12,
                      blurRadius: 10.r,
                      offset: const Offset(0, 4),
                    ),
                  ],
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Padding(
                      padding: EdgeInsets.fromLTRB(16.w, 12.h, 16.w, 0),
                      child: Text(
                        widget.message,
                        style: TextStyle(
                          fontSize: 14.sp,
                          fontWeight: FontWeight.w500,
                          color: Colors.black87,
                        ),
                      ),
                    ),
                    SizedBox(height: 12.h),
                    TweenAnimationBuilder<double>(
                      duration: Duration(milliseconds: widget.duration),
                      tween: Tween(begin: 1, end: 0),
                      builder: (_, value, _) {
                        return LinearProgressIndicator(
                          value: value,
                          color: widget.indicatorColor,
                          backgroundColor: Colors.transparent,
                          minHeight: 4.h,
                        );
                      },
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
