import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';

/// Loading indicator variant types
enum CoreLoadingVariant {
  /// Material Design circular progress indicator
  material,
  /// iOS style activity indicator
  cupertino,
  /// Custom Lottie animation
  lottie,
  /// Linear progress indicator
  linear,
}

/// Loading indicator size presets
enum CoreLoadingSize {
  /// Small - 16x16
  small,
  /// Medium - 24x24 (default)
  medium,
  /// Large - 32x32
  large,
  /// Extra large - 48x48
  extraLarge,
}

/// A unified loading indicator widget that replaces inconsistent loading patterns
/// 
/// This widget provides consistent loading states across the entire app with
/// support for different variants, sizes, colors, and text labels.
class CoreLoadingIndicator extends StatelessWidget {
  /// Loading indicator variant
  final CoreLoadingVariant variant;
  
  /// Size preset
  final CoreLoadingSize size;
  
  /// Custom width (overrides size preset)
  final double? width;
  
  /// Custom height (overrides size preset)
  final double? height;
  
  /// Indicator color
  final Color? color;
  
  /// Progress value for determinate indicators (0.0 to 1.0)
  final double? value;
  
  /// Stroke width for circular indicators
  final double? strokeWidth;
  
  /// Loading text label
  final String? label;
  
  /// Text style for label
  final TextStyle? labelStyle;
  
  /// Spacing between indicator and label
  final double labelSpacing;
  
  /// Label position relative to indicator
  final CrossAxisAlignment labelAlignment;

  const CoreLoadingIndicator({
    super.key,
    this.variant = CoreLoadingVariant.material,
    this.size = CoreLoadingSize.medium,
    this.width,
    this.height,
    this.color,
    this.value,
    this.strokeWidth,
    this.label,
    this.labelStyle,
    this.labelSpacing = 12.0,
    this.labelAlignment = CrossAxisAlignment.center,
  });

  /// Creates a small Material loading indicator
  const CoreLoadingIndicator.small({
    super.key,
    this.color,
    this.value,
    this.strokeWidth,
    this.label,
    this.labelStyle,
    this.labelSpacing = 8.0,
    this.labelAlignment = CrossAxisAlignment.center,
  }) : variant = CoreLoadingVariant.material,
       size = CoreLoadingSize.small,
       width = null,
       height = null;

  /// Creates a Cupertino style activity indicator
  const CoreLoadingIndicator.cupertino({
    super.key,
    this.size = CoreLoadingSize.medium,
    this.width,
    this.height,
    this.color,
    this.label,
    this.labelStyle,
    this.labelSpacing = 12.0,
    this.labelAlignment = CrossAxisAlignment.center,
  }) : variant = CoreLoadingVariant.cupertino,
       value = null,
       strokeWidth = null;

  /// Creates a linear progress indicator
  const CoreLoadingIndicator.linear({
    super.key,
    this.width,
    this.height = 4.0,
    this.color,
    this.value,
    this.label,
    this.labelStyle,
    this.labelSpacing = 8.0,
    this.labelAlignment = CrossAxisAlignment.start,
  }) : variant = CoreLoadingVariant.linear,
       size = CoreLoadingSize.medium,
       strokeWidth = null;

  /// Creates a large Lottie animation loading indicator
  const CoreLoadingIndicator.lottie({
    super.key,
    this.size = CoreLoadingSize.large,
    this.width,
    this.height,
    this.label,
    this.labelStyle,
    this.labelSpacing = 16.0,
    this.labelAlignment = CrossAxisAlignment.center,
  }) : variant = CoreLoadingVariant.lottie,
       color = null,
       value = null,
       strokeWidth = null;

  /// Gets size dimensions based on size preset
  Size get _indicatorSize {
    final sizeValue = width ?? height ?? _defaultSize;
    return Size(sizeValue, sizeValue);
  }

  double get _defaultSize {
    switch (size) {
      case CoreLoadingSize.small:
        return 16.0;
      case CoreLoadingSize.medium:
        return 24.0;
      case CoreLoadingSize.large:
        return 32.0;
      case CoreLoadingSize.extraLarge:
        return 48.0;
    }
  }

  Color get _indicatorColor {
    return color ?? AppColor.blueNormal;
  }

  Widget _buildIndicator() {
    final indicatorSize = _indicatorSize;
    
    switch (variant) {
      case CoreLoadingVariant.material:
        return SizedBox(
          width: indicatorSize.width,
          height: indicatorSize.height,
          child: CircularProgressIndicator(
            value: value,
            strokeWidth: strokeWidth ?? (indicatorSize.width * 0.08).clamp(1.5, 4.0),
            valueColor: AlwaysStoppedAnimation<Color>(_indicatorColor),
          ),
        );
        
      case CoreLoadingVariant.cupertino:
        return SizedBox(
          width: indicatorSize.width,
          height: indicatorSize.height,
          child: CupertinoActivityIndicator(
            color: _indicatorColor,
            radius: indicatorSize.width * 0.4,
          ),
        );
        
      case CoreLoadingVariant.linear:
        return SizedBox(
          width: width ?? 200.0,
          height: height ?? 4.0,
          child: LinearProgressIndicator(
            value: value,
            backgroundColor: _indicatorColor.withOpacity(0.2),
            valueColor: AlwaysStoppedAnimation<Color>(_indicatorColor),
          ),
        );
        
      case CoreLoadingVariant.lottie:
        try {
          return Assets.anim.loading.lottie(
            width: indicatorSize.width,
            height: indicatorSize.height,
          );
        } catch (e) {
          // Fallback to Material indicator if Lottie fails
          return SizedBox(
            width: indicatorSize.width,
            height: indicatorSize.height,
            child: CircularProgressIndicator(
              strokeWidth: strokeWidth ?? 3.0,
              valueColor: AlwaysStoppedAnimation<Color>(_indicatorColor),
            ),
          );
        }
    }
  }

  Widget _buildLabel() {
    if (label == null) return const SizedBox.shrink();
    
    return Text(
      label!,
      style: labelStyle ?? AppFonts.yekan14.copyWith(
        color: AppColor.textColor,
      ),
      textAlign: TextAlign.center,
    );
  }

  @override
  Widget build(BuildContext context) {
    final indicator = _buildIndicator();
    final labelWidget = _buildLabel();
    
    if (label == null) {
      return indicator;
    }
    
    if (variant == CoreLoadingVariant.linear) {
      return Column(
        crossAxisAlignment: labelAlignment,
        mainAxisSize: MainAxisSize.min,
        children: [
          labelWidget,
          SizedBox(height: labelSpacing),
          indicator,
        ],
      );
    }
    
    return Column(
      crossAxisAlignment: labelAlignment,
      mainAxisSize: MainAxisSize.min,
      children: [
        indicator,
        SizedBox(height: labelSpacing),
        labelWidget,
      ],
    );
  }
}

/// A full-screen loading overlay widget
class CoreLoadingOverlay extends StatelessWidget {
  /// Loading indicator to display
  final CoreLoadingIndicator indicator;
  
  /// Background color of the overlay
  final Color backgroundColor;
  
  /// Whether the overlay should block user interaction
  final bool barrierDismissible;

  const CoreLoadingOverlay({
    super.key,
    this.indicator = const CoreLoadingIndicator.lottie(
      label: 'در حال بارگذاری...',
    ),
    this.backgroundColor = Colors.black54,
    this.barrierDismissible = false,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      color: backgroundColor,
      child: Center(child: indicator),
    );
  }
  
  /// Shows a loading overlay on top of current screen
  static void show(
    BuildContext context, {
    CoreLoadingIndicator? indicator,
    Color backgroundColor = Colors.black54,
    bool barrierDismissible = false,
  }) {
    showDialog(
      context: context,
      barrierDismissible: barrierDismissible,
      barrierColor: Colors.transparent,
      builder: (context) => CoreLoadingOverlay(
        indicator: indicator ?? const CoreLoadingIndicator.lottie(
          label: 'در حال بارگذاری...',
        ),
        backgroundColor: backgroundColor,
        barrierDismissible: barrierDismissible,
      ),
    );
  }
  
  /// Hides the currently displayed loading overlay
  static void hide(BuildContext context) {
    Navigator.of(context).pop();
  }
}