import 'package:flutter/foundation.dart';
import 'logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'dart:async';

/// 성능 최적화를 위한 유틸리티 클래스
class PerformanceOptimizer {
  static final PerformanceOptimizer _instance =
      PerformanceOptimizer._internal();
  factory PerformanceOptimizer() => _instance;
  PerformanceOptimizer._internal();

  // 프레임 타이밍 정보
  final List<FrameTiming> _frameTimings = [];
  bool _isMonitoring = false;

  /// 프레임 성능 모니터링 시작
  void startFrameMonitoring() {
    if (_isMonitoring) return;
    _isMonitoring = true;

    SchedulerBinding.instance.addTimingsCallback((timings) {
      _frameTimings.addAll(timings);
      // 최근 100개 프레임만 유지
      if (_frameTimings.length > 100) {
        _frameTimings.removeRange(0, _frameTimings.length - 100);
      }
    });
  }

  /// 프레임 성능 모니터링 중지
  void stopFrameMonitoring() {
    if (!_isMonitoring) return;
    _isMonitoring = false;
    SchedulerBinding.instance.addTimingsCallback((_) {});
  }

  /// 평균 FPS 계산
  double getAverageFPS() {
    if (_frameTimings.isEmpty) return 0.0;

    double totalDuration = 0;
    for (final timing in _frameTimings) {
      totalDuration += timing.totalSpan.inMicroseconds;
    }

    final averageDuration = totalDuration / _frameTimings.length;
    return 1000000 / averageDuration; // microseconds to FPS
  }

  /// 메모리 사용량 모니터링
  static Future<MemoryInfo> getMemoryInfo() async {
    // Flutter에서는 직접적인 메모리 사용량 측정이 제한적이므로
    // 이미지 캐시 사용량을 기준으로 측정
    final imageCache = PaintingBinding.instance.imageCache;
    return MemoryInfo(
      currentUsage: imageCache.currentSizeBytes,
      capacity: imageCache.maximumSizeBytes,
    );
  }

  /// 위젯 재빌드 최적화를 위한 데바운서
  static Timer? _debounceTimer;
  static void debounce(
    VoidCallback callback, {
    Duration delay = const Duration(milliseconds: 300),
  }) {
    _debounceTimer?.cancel();
    _debounceTimer = Timer(delay, callback);
  }

  /// 스로틀링 - 지정된 시간 간격으로만 실행
  static DateTime? _lastThrottleTime;
  static void throttle(
    VoidCallback callback, {
    Duration interval = const Duration(milliseconds: 300),
  }) {
    final now = DateTime.now();
    if (_lastThrottleTime == null ||
        now.difference(_lastThrottleTime!) > interval) {
      _lastThrottleTime = now;
      callback();
    }
  }

  /// 무거운 연산을 별도 Isolate에서 실행
  static Future<T> runInIsolate<T>(
    ComputeCallback<dynamic, T> callback,
    dynamic parameter,
  ) async {
    return await compute(callback, parameter);
  }

  /// 레이지 로딩을 위한 페이지네이션 헬퍼
  static List<T> paginate<T>({
    required List<T> items,
    required int page,
    required int pageSize,
  }) {
    final startIndex = page * pageSize;
    final endIndex = (startIndex + pageSize).clamp(0, items.length);

    if (startIndex >= items.length) return [];
    return items.sublist(startIndex, endIndex);
  }

  /// 이미지 최적화 - 메모리 효율적인 크기로 조정
  static double getOptimalImageSize(
    BuildContext context, {
    required double originalSize,
    double maxSize = 1000,
  }) {
    final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
    final screenSize = MediaQuery.of(context).size;
    final maxDimension = screenSize.width > screenSize.height
        ? screenSize.width
        : screenSize.height;

    final optimalSize = (maxDimension * devicePixelRatio).clamp(100.0, maxSize);
    return optimalSize < originalSize ? optimalSize : originalSize;
  }

  /// 위젯 키 최적화
  static Key generateOptimizedKey(String prefix, dynamic identifier) {
    return ValueKey('${prefix}_$identifier');
  }

  /// 애니메이션 최적화 - 보이지 않는 애니메이션 중지
  static bool shouldAnimateWidget(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    return !mediaQuery.disableAnimations && mediaQuery.accessibleNavigation;
  }

  /// 스크롤 성능 최적화
  static ScrollPhysics getOptimizedScrollPhysics() {
    return const BouncingScrollPhysics(
      parent: AlwaysScrollableScrollPhysics(),
    );
  }

  /// 빌드 최적화를 위한 const 위젯 권장사항 체크
  static void checkConstOptimization() {
    if (kDebugMode) {
      Log.i('💡 성능 최적화 팁:\n'
          '1. 가능한 모든 위젯에 const 사용\n'
          '2. StatelessWidget 대신 const 생성자 사용\n'
          '3. 큰 리스트는 ListView.builder 사용\n'
          '4. 이미지는 캐싱과 함께 적절한 크기로 로드\n'
          '5. 애니메이션은 AnimatedBuilder 사용');
    }
  }

  /// 메모리 누수 감지 헬퍼
  static final Map<String, int> _widgetCounts = {};

  static void trackWidget(String widgetName, bool isCreated) {
    if (!kDebugMode) return;

    _widgetCounts[widgetName] =
        (_widgetCounts[widgetName] ?? 0) + (isCreated ? 1 : -1);

    // 위젯이 비정상적으로 많이 생성되면 경고
    if ((_widgetCounts[widgetName] ?? 0) > 100) {
      Log.w('경고: $widgetName 위젯이 100개 이상 생성됨. 메모리 누수 가능성!');
    }
  }
}

/// 메모리 정보 클래스
class MemoryInfo {
  final int currentUsage;
  final int capacity;

  MemoryInfo({
    required this.currentUsage,
    required this.capacity,
  });

  double get usagePercentage => (currentUsage / capacity) * 100;

  String get formattedUsage =>
      '${(currentUsage / 1024 / 1024).toStringAsFixed(2)} MB';
  String get formattedCapacity =>
      '${(capacity / 1024 / 1024).toStringAsFixed(2)} MB';
}

/// 성능 측정 데코레이터
class PerformanceMeasure {
  static Future<T> measure<T>({
    required String name,
    required Future<T> Function() operation,
  }) async {
    if (!kDebugMode) return await operation();

    final stopwatch = Stopwatch()..start();
    try {
      final result = await operation();
      stopwatch.stop();
      Log.d('✅ $name 완료: ${stopwatch.elapsedMilliseconds}ms');
      return result;
    } catch (e) {
      stopwatch.stop();
      Log.e('❌ $name 실패: ${stopwatch.elapsedMilliseconds}ms', e);
      rethrow;
    }
  }
}
