import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart' as flutter_test;

/// 테스트 환경에서 사용할 유틸리티 함수들을 제공하는 클래스
class TestUtils {
  /// 테스트 모드 강제 설정 (테스트에서 명시적으로 설정 가능)
  static bool _forceTestMode = false;
  
  /// 테스트 모드 강제 설정
  static void setTestMode(bool isTest) {
    _forceTestMode = isTest;
  }
  
  /// 현재 테스트 환경인지 확인 (개선된 버전)
  static bool get isInTest {
    // 강제 설정된 경우 해당 값 반환
    if (_forceTestMode) {
      return true;
    }
    
    // 다양한 방법으로 테스트 환경 감지 시도
    try {
      // 방법 1: flutter_test 라이브러리의 속성 확인
      return flutter_test.WidgetController.hitTestWarningShouldBeFatal;
    } catch (_) {
      try {
        // 방법 2: 테스트 환경에서만 존재하는 Zone 속성 확인
        return Zone.current['_testZoneSpecification'] != null;
      } catch (_) {
        try {
          // 방법 3: 디버그 모드 확인 (완벽한 방법은 아니지만 대안)
          return kDebugMode;
        } catch (_) {
          return false;
        }
      }
    }
  }
  
  /// 테스트용 고정 해시 생성 (테스트에서 예측 가능한 결과를 위해)
  static int _testHashCounter = 0;
  
  /// 테스트 환경에서 사용할 예측 가능한 해시 생성
  static String getTestHash() {
    _testHashCounter++;
    final counter = _testHashCounter.toString().padLeft(2, '0');
    return 'test$counter';
  }
  
  /// 현재 타이머가 활성화되어 있는지 확인
  /// 테스트 종료 시 !timersPending assertion 실패 원인 추적용
  static bool isTimerPending() {
    try {
      // flutter_test 라이브러리의 테스트 환경에서만 사용 가능
      if (isInTest) {
        // Zone 속성을 통해 타이머 상태 확인 시도
        final zone = Zone.current;
        if (zone['_timerCount'] != null) {
          return zone['_timerCount'] > 0;
        }
        
        // 다른 방법으로 타이머 상태 확인 시도
        try {
          // SchedulerBinding을 통해 프레임 스케줄링 상태 확인
          return SchedulerBinding.instance.hasScheduledFrame ||
                 SchedulerBinding.instance.transientCallbackCount > 0;
        } catch (_) {
          // 실패 시 기본값 반환
          return false;
        }
      }
    } catch (e) {
      if (kDebugMode) {
        debugPrint('타이머 상태 확인 중 오류: $e');
      }
    }
    
    // 테스트 환경이 아니거나 오류 발생 시 기본값 반환
    return false;
  }
  
  /// 테스트 환경에서 사용할 예측 가능한 해시 생성 (테스트 파일과의 호환성을 위한 별칭)
  static String generatePredictableHash() {
    return getTestHash();
  }

  /// 테스트 환경에서 애니메이션을 비활성화하는 위젯
  static Widget disableAnimations({required Widget child}) {
    if (!isInTest) {
      return child;
    }
    
    return MediaQuery(
      data: const MediaQueryData(
        textScaler: TextScaler.linear(1.0),
        platformBrightness: Brightness.light,
        padding: EdgeInsets.zero,
        viewInsets: EdgeInsets.zero,
        devicePixelRatio: 1.0,
        size: Size(800, 600),
      ),
      child: AnimatedBuilder(
        animation: const AlwaysStoppedAnimation<double>(1.0),
        builder: (BuildContext context, Widget? child) {
          return child!;
        },
        child: child,
      ),
    );
  }

  /// 테스트 환경에서 안전하게 SnackBar를 표시하는 함수
  static void showSnackBarSafely(BuildContext context, SnackBar snackBar) {
    if (!isInTest) {
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
      return;
    }
    
    // 테스트 환경에서는 SnackBar 표시 대신 로그만 출력
    debugPrint('테스트 환경에서 SnackBar 표시 (내용: ${snackBar.content})');
  }
  
  /// 테스트 환경에서 안전하게 현재 SnackBar를 숨기는 함수
  static void hideCurrentSnackBarSafely(BuildContext context) {
    if (!isInTest) {
      ScaffoldMessenger.of(context).hideCurrentSnackBar();
      return;
    }
    
    // 테스트 환경에서는 로그만 출력
    debugPrint('테스트 환경에서 현재 SnackBar 숨김');
  }
}
