import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:visibility_detector/visibility_detector.dart';

/// 数据加载状态
enum LoadState {
  /// 未开始加载
  idle,
  /// 加载中
  loading,
  /// 加载成功
  success,
  /// 加载失败
  error,
}

/// 懒加载区域组件
///
/// 当区域进入可视区域时自动触发数据加载，支持：
/// - 懒加载：滚动到可见时才加载
/// - 失败重试：支持手动重试和自动重试
/// - 骨架屏：加载中显示 Shimmer 效果
/// - 错误状态：显示错误信息和重试按钮
class LazyLoadSection extends StatefulWidget {
  /// 唯一标识符，用于 VisibilityDetector
  final String sectionKey;

  /// 数据加载函数，返回 Future
  final Future<void> Function() onLoad;

  /// 加载成功后显示的内容
  final Widget child;

  /// 骨架屏高度（可选，默认 100）
  final double skeletonHeight;

  /// 自定义骨架屏（可选）
  final Widget? skeleton;

  /// 自定义错误组件（可选）
  final Widget Function(String error, VoidCallback retry)? errorBuilder;

  /// 最大重试次数（默认 3 次）
  final int maxRetries;

  /// 重试延迟基数（毫秒，指数退避）
  final int retryDelayMs;

  /// 可见度阈值（0-1，默认 0.1 表示 10% 可见时触发）
  final double visibilityThreshold;

  /// 是否立即加载（不等待可见，用于首屏数据）
  final bool loadImmediately;

  const LazyLoadSection({
    super.key,
    required this.sectionKey,
    required this.onLoad,
    required this.child,
    this.skeletonHeight = 100,
    this.skeleton,
    this.errorBuilder,
    this.maxRetries = 3,
    this.retryDelayMs = 1000,
    this.visibilityThreshold = 0.1,
    this.loadImmediately = false,
  });

  @override
  State<LazyLoadSection> createState() => _LazyLoadSectionState();
}

class _LazyLoadSectionState extends State<LazyLoadSection> {
  LoadState _state = LoadState.idle;
  String _errorMessage = '';
  int _retryCount = 0;
  bool _hasBeenVisible = false;

  @override
  void initState() {
    super.initState();
    if (widget.loadImmediately) {
      _loadData();
    }
  }

  /// 执行数据加载
  Future<void> _loadData() async {
    if (_state == LoadState.loading) return;

    setState(() {
      _state = LoadState.loading;
      _errorMessage = '';
    });

    try {
      await widget.onLoad();
      if (mounted) {
        setState(() {
          _state = LoadState.success;
          _retryCount = 0;
        });
      }
    } catch (e) {
      debugPrint('[LazyLoadSection] ${widget.sectionKey} 加载失败: $e');
      if (mounted) {
        setState(() {
          _state = LoadState.error;
          _errorMessage = e.toString().replaceAll('Exception: ', '');
        });
        // 自动重试
        _scheduleAutoRetry();
      }
    }
  }

  /// 安排自动重试（指数退避）
  void _scheduleAutoRetry() {
    if (_retryCount >= widget.maxRetries) {
      debugPrint('[LazyLoadSection] ${widget.sectionKey} 已达最大重试次数');
      return;
    }

    final delay = widget.retryDelayMs * (1 << _retryCount); // 指数退避
    debugPrint('[LazyLoadSection] ${widget.sectionKey} 将在 ${delay}ms 后重试 (第 ${_retryCount + 1} 次)');

    Future.delayed(Duration(milliseconds: delay), () {
      if (mounted && _state == LoadState.error) {
        _retryCount++;
        _loadData();
      }
    });
  }

  /// 手动重试
  void _manualRetry() {
    _retryCount = 0;
    _loadData();
  }

  /// 处理可见性变化
  void _onVisibilityChanged(VisibilityInfo info) {
    if (_hasBeenVisible) return;

    if (info.visibleFraction >= widget.visibilityThreshold) {
      _hasBeenVisible = true;
      if (_state == LoadState.idle) {
        _loadData();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return VisibilityDetector(
      key: Key('lazy_${widget.sectionKey}'),
      onVisibilityChanged: _onVisibilityChanged,
      child: _buildContent(),
    );
  }

  Widget _buildContent() {
    switch (_state) {
      case LoadState.idle:
      case LoadState.loading:
        return _buildSkeleton();
      case LoadState.error:
        return _buildError();
      case LoadState.success:
        return widget.child;
    }
  }

  /// 构建骨架屏
  Widget _buildSkeleton() {
    if (widget.skeleton != null) {
      return widget.skeleton!;
    }

    return Shimmer.fromColors(
      baseColor: const Color(0xFFE0E0E0),
      highlightColor: const Color(0xFFF5F5F5),
      child: Container(
        height: widget.skeletonHeight,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8),
        ),
      ),
    );
  }

  /// 构建错误状态
  Widget _buildError() {
    if (widget.errorBuilder != null) {
      return widget.errorBuilder!(_errorMessage, _manualRetry);
    }

    return Container(
      height: widget.skeletonHeight,
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: const Color(0xFFFFF3E0),
        borderRadius: BorderRadius.circular(8),
        border: Border.all(
          color: const Color(0xFFFFCC80),
          width: 1,
        ),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Icon(
            Icons.error_outline,
            color: Color(0xFFE65100),
            size: 24,
          ),
          const SizedBox(height: 8),
          Text(
            _retryCount >= widget.maxRetries
                ? '加载失败，点击重试'
                : '加载失败，正在重试...',
            style: const TextStyle(
              fontSize: 12,
              color: Color(0xFFE65100),
            ),
            textAlign: TextAlign.center,
          ),
          if (_retryCount >= widget.maxRetries) ...[
            const SizedBox(height: 8),
            GestureDetector(
              onTap: _manualRetry,
              child: Container(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
                decoration: BoxDecoration(
                  color: const Color(0xFFD4AF37),
                  borderRadius: BorderRadius.circular(4),
                ),
                child: const Text(
                  '重试',
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.white,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }
}

/// 带下拉刷新的懒加载列表包装器
class LazyLoadRefreshWrapper extends StatelessWidget {
  final Widget child;
  final Future<void> Function() onRefresh;

  const LazyLoadRefreshWrapper({
    super.key,
    required this.child,
    required this.onRefresh,
  });

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: onRefresh,
      color: const Color(0xFFD4AF37),
      backgroundColor: Colors.white,
      child: child,
    );
  }
}
