import 'package:flutter/material.dart';

/// Reusable loading indicator widget
///
/// Provides different loading indicator variants:
/// - Circular (default)
/// - Linear
/// - Overlay (full screen with backdrop)
/// - With message
///
/// Usage:
/// ```dart
/// // Simple circular indicator
/// LoadingIndicator()
///
/// // With custom size and color
/// LoadingIndicator(
///   size: 50,
///   color: Colors.blue,
/// )
///
/// // Linear indicator
/// LoadingIndicator.linear()
///
/// // Full screen overlay
/// LoadingIndicator.overlay(
///   message: 'Loading data...',
/// )
///
/// // Centered with message
/// LoadingIndicator.withMessage(
///   message: 'Please wait...',
/// )
/// ```
class LoadingIndicator extends StatelessWidget {
  /// Size of the loading indicator
  final double? size;

  /// Color of the loading indicator
  final Color? color;

  /// Stroke width for circular indicator
  final double strokeWidth;

  /// Whether to use linear progress indicator
  final bool isLinear;

  /// Optional loading message
  final String? message;

  /// Text style for the message
  final TextStyle? messageStyle;

  /// Spacing between indicator and message
  final double messageSpacing;

  const LoadingIndicator({
    super.key,
    this.size,
    this.color,
    this.strokeWidth = 4.0,
    this.message,
    this.messageStyle,
    this.messageSpacing = 16.0,
  }) : isLinear = false;

  /// Create a linear loading indicator
  const LoadingIndicator.linear({
    super.key,
    this.color,
    this.message,
    this.messageStyle,
    this.messageSpacing = 16.0,
  })  : isLinear = true,
        size = null,
        strokeWidth = 4.0;

  /// Create a full-screen loading overlay
  static Widget overlay({
    String? message,
    Color? backgroundColor,
    Color? indicatorColor,
    TextStyle? messageStyle,
  }) {
    return _LoadingOverlay(
      message: message,
      backgroundColor: backgroundColor,
      indicatorColor: indicatorColor,
      messageStyle: messageStyle,
    );
  }

  /// Create a loading indicator with a message below it
  static Widget withMessage({
    required String message,
    double size = 40,
    Color? color,
    TextStyle? messageStyle,
    double spacing = 16.0,
  }) {
    return LoadingIndicator(
      size: size,
      color: color,
      message: message,
      messageStyle: messageStyle,
      messageSpacing: spacing,
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final indicatorColor = color ?? theme.colorScheme.primary;

    Widget indicator;
    if (isLinear) {
      indicator = LinearProgressIndicator(
        color: indicatorColor,
        backgroundColor: indicatorColor.withOpacity(0.1),
      );
    } else {
      indicator = SizedBox(
        width: size ?? 40,
        height: size ?? 40,
        child: CircularProgressIndicator(
          color: indicatorColor,
          strokeWidth: strokeWidth,
        ),
      );
    }

    // If there's no message, return just the indicator
    if (message == null) {
      return indicator;
    }

    // If there's a message, wrap in column
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        indicator,
        SizedBox(height: messageSpacing),
        Text(
          message!,
          style: messageStyle ??
              theme.textTheme.bodyMedium?.copyWith(
                color: theme.colorScheme.onSurface.withOpacity(0.7),
              ),
          textAlign: TextAlign.center,
        ),
      ],
    );
  }
}

/// Full-screen loading overlay
class _LoadingOverlay extends StatelessWidget {
  final String? message;
  final Color? backgroundColor;
  final Color? indicatorColor;
  final TextStyle? messageStyle;

  const _LoadingOverlay({
    this.message,
    this.backgroundColor,
    this.indicatorColor,
    this.messageStyle,
  });

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Container(
      color: backgroundColor ?? Colors.black.withOpacity(0.5),
      child: Center(
        child: Card(
          elevation: 8,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
          ),
          child: Padding(
            padding: const EdgeInsets.all(24.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: 50,
                  height: 50,
                  child: CircularProgressIndicator(
                    color: indicatorColor ?? theme.colorScheme.primary,
                    strokeWidth: 4,
                  ),
                ),
                if (message != null) ...[
                  const SizedBox(height: 24),
                  SizedBox(
                    width: 200,
                    child: Text(
                      message!,
                      style: messageStyle ?? theme.textTheme.bodyLarge,
                      textAlign: TextAlign.center,
                    ),
                  ),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}

/// Shimmer loading effect for list items
class ShimmerLoading extends StatefulWidget {
  /// Width of the shimmer container
  final double? width;

  /// Height of the shimmer container
  final double height;

  /// Border radius
  final double borderRadius;

  /// Base color
  final Color? baseColor;

  /// Highlight color
  final Color? highlightColor;

  const ShimmerLoading({
    super.key,
    this.width,
    this.height = 16,
    this.borderRadius = 4,
    this.baseColor,
    this.highlightColor,
  });

  @override
  State<ShimmerLoading> createState() => _ShimmerLoadingState();
}

class _ShimmerLoadingState extends State<ShimmerLoading>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

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

    _animation = Tween<double>(begin: -1.0, end: 2.0).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final baseColor = widget.baseColor ?? theme.colorScheme.surfaceVariant;
    final highlightColor =
        widget.highlightColor ?? theme.colorScheme.surface;

    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return Container(
          width: widget.width,
          height: widget.height,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(widget.borderRadius),
            gradient: LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: [
                baseColor,
                highlightColor,
                baseColor,
              ],
              stops: [
                0.0,
                _animation.value,
                1.0,
              ],
            ),
          ),
        );
      },
    );
  }
}

/// Loading state for list items
class ListLoadingIndicator extends StatelessWidget {
  /// Number of shimmer items to show
  final int itemCount;

  /// Height of each item
  final double itemHeight;

  /// Spacing between items
  final double spacing;

  const ListLoadingIndicator({
    super.key,
    this.itemCount = 5,
    this.itemHeight = 80,
    this.spacing = 12,
  });

  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: itemCount,
      separatorBuilder: (context, index) => SizedBox(height: spacing),
      itemBuilder: (context, index) => ShimmerLoading(
        height: itemHeight,
        width: double.infinity,
        borderRadius: 8,
      ),
    );
  }
}
