import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:superport/core/utils/debug_logger.dart';
import 'package:superport/core/config/environment.dart' as env;

/// 로그인 문제 진단을 위한 유틸리티 클래스
class LoginDiagnostics {
  /// 로그인 프로세스 전체 진단
  static Future<Map<String, dynamic>> runFullDiagnostics() async {
    final results = <String, dynamic>{};
    
    try {
      // 1. 환경 설정 확인
      results['environment'] = _checkEnvironment();
      
      // 2. 네트워크 연결 확인
      results['network'] = await _checkNetworkConnectivity();
      
      // 3. API 엔드포인트 확인
      results['apiEndpoint'] = await _checkApiEndpoint();
      
      // 4. 모델 직렬화 테스트
      results['serialization'] = _testSerialization();
      
      // 5. 저장소 접근 테스트
      results['storage'] = await _testStorageAccess();
      
      DebugLogger.log(
        '로그인 진단 완료',
        tag: 'DIAGNOSTICS',
        data: results,
      );
      
      return results;
    } catch (e, stackTrace) {
      DebugLogger.logError(
        '진단 중 오류 발생',
        error: e,
        stackTrace: stackTrace,
      );
      return {
        'error': e.toString(),
        'stackTrace': stackTrace.toString(),
      };
    }
  }
  
  /// 환경 설정 확인
  static Map<String, dynamic> _checkEnvironment() {
    return {
      'apiBaseUrl': env.Environment.apiBaseUrl,
      'isDebugMode': kDebugMode,
      'platform': defaultTargetPlatform.toString(),
    };
  }
  
  /// 네트워크 연결 확인
  static Future<Map<String, dynamic>> _checkNetworkConnectivity() async {
    final dio = Dio();
    final results = <String, dynamic>{};
    
    try {
      // Google DNS로 연결 테스트
      final response = await dio.get('https://dns.google/resolve?name=google.com');
      results['internetConnection'] = response.statusCode == 200;
    } catch (e) {
      results['internetConnection'] = false;
      results['error'] = e.toString();
    }
    
    // API 서버 연결 테스트
    try {
      final response = await dio.get(
        '${env.Environment.apiBaseUrl}/health',
        options: Options(
          validateStatus: (status) => status != null && status < 500,
        ),
      );
      results['apiServerReachable'] = true;
      results['apiServerStatus'] = response.statusCode;
    } catch (e) {
      results['apiServerReachable'] = false;
      results['apiServerError'] = e.toString();
    }
    
    return results;
  }
  
  /// API 엔드포인트 확인
  static Future<Map<String, dynamic>> _checkApiEndpoint() async {
    
    final dio = Dio();
    final results = <String, dynamic>{};
    
    try {
      // OPTIONS 요청으로 CORS 확인
      final response = await dio.request(
        '${env.Environment.apiBaseUrl}/auth/login',
        options: Options(
          method: 'OPTIONS',
          validateStatus: (status) => true,
        ),
      );
      
      results['corsEnabled'] = response.statusCode == 200 || response.statusCode == 204;
      results['allowedMethods'] = response.headers['access-control-allow-methods'];
      results['allowedHeaders'] = response.headers['access-control-allow-headers'];
      
      // 실제 로그인 엔드포인트 테스트 (잘못된 자격 증명으로)
      final loginResponse = await dio.post(
        '${env.Environment.apiBaseUrl}/auth/login',
        data: {
          'email': 'test@test.com',
          'password': 'test',
        },
        options: Options(
          validateStatus: (status) => true,
        ),
      );
      
      results['loginEndpointStatus'] = loginResponse.statusCode;
      results['loginResponseType'] = loginResponse.data?.runtimeType.toString();
      
      // 응답 구조 분석
      if (loginResponse.data is Map) {
        final data = loginResponse.data as Map;
        results['responseKeys'] = data.keys.toList();
        results['hasSuccessField'] = data.containsKey('success');
        results['hasDataField'] = data.containsKey('data');
        results['hasAccessToken'] = data.containsKey('accessToken') || data.containsKey('access_token');
      }
      
    } catch (e) {
      results['error'] = e.toString();
      if (e is DioException) {
        results['dioErrorType'] = e.type.toString();
        results['dioMessage'] = e.message;
      }
    }
    
    return results;
  }
  
  /// 모델 직렬화 테스트
  static Map<String, dynamic> _testSerialization() {
    final results = <String, dynamic>{};
    
    try {
      // LoginRequest 테스트
      results['loginRequestValid'] = true;
      
      // LoginResponse 테스트 (형식 1)
      final loginResponse1 = {
        'success': true,
        'data': {
          'accessToken': 'test_token',
          'refreshToken': 'refresh_token',
          'tokenType': 'Bearer',
          'expiresIn': 3600,
          'user': {
            'id': 1,
            'username': 'testuser',
            'email': 'test@example.com',
            'name': '테스트',
            'role': 'USER',
          },
        },
      };
      
      results['format1Valid'] = _validateResponseFormat1(loginResponse1);
      
      // LoginResponse 테스트 (형식 2)
      final loginResponse2 = {
        'accessToken': 'test_token',
        'refreshToken': 'refresh_token',
        'tokenType': 'Bearer',
        'expiresIn': 3600,
        'user': {
          'id': 1,
          'username': 'testuser',
          'email': 'test@example.com',
          'name': '테스트',
          'role': 'USER',
        },
      };
      
      results['format2Valid'] = _validateResponseFormat2(loginResponse2);
      
    } catch (e) {
      results['error'] = e.toString();
    }
    
    return results;
  }
  
  /// 저장소 접근 테스트
  static Future<Map<String, dynamic>> _testStorageAccess() async {
    final results = <String, dynamic>{};
    
    try {
      // 실제 FlutterSecureStorage 테스트는 의존성 주입이 필요하므로
      // 여기서는 기본적인 체크만 수행
      results['platformSupported'] = true;
      
      // 플랫폼별 특이사항 체크
      if (defaultTargetPlatform == TargetPlatform.iOS) {
        results['note'] = 'iOS Keychain 사용';
      } else if (defaultTargetPlatform == TargetPlatform.android) {
        results['note'] = 'Android KeyStore 사용';
      } else {
        results['note'] = '웹 또는 데스크톱 플랫폼';
      }
      
    } catch (e) {
      results['error'] = e.toString();
    }
    
    return results;
  }
  
  /// 응답 형식 1 검증
  static bool _validateResponseFormat1(Map<String, dynamic> response) {
    try {
      if (!response.containsKey('success') || response['success'] != true) {
        return false;
      }
      
      if (!response.containsKey('data') || response['data'] is! Map) {
        return false;
      }
      
      final data = response['data'] as Map<String, dynamic>;
      final requiredFields = ['accessToken', 'refreshToken', 'user'];
      
      for (final field in requiredFields) {
        if (!data.containsKey(field)) {
          return false;
        }
      }
      
      return true;
    } catch (e) {
      return false;
    }
  }
  
  /// 응답 형식 2 검증
  static bool _validateResponseFormat2(Map<String, dynamic> response) {
    try {
      final requiredFields = ['accessToken', 'refreshToken', 'user'];
      
      for (final field in requiredFields) {
        if (!response.containsKey(field)) {
          return false;
        }
      }
      
      if (response['user'] is! Map) {
        return false;
      }
      
      return true;
    } catch (e) {
      return false;
    }
  }
  
  /// 진단 결과를 읽기 쉬운 형식으로 포맷
  static String formatDiagnosticsReport(Map<String, dynamic> diagnostics) {
    final buffer = StringBuffer();
    
    buffer.writeln('=== 로그인 진단 보고서 ===\n');
    
    // 환경 설정
    if (diagnostics.containsKey('environment')) {
      buffer.writeln('## 환경 설정');
      final env = diagnostics['environment'] as Map<String, dynamic>;
      env.forEach((key, value) {
        buffer.writeln('- $key: $value');
      });
      buffer.writeln();
    }
    
    // 네트워크 상태
    if (diagnostics.containsKey('network')) {
      buffer.writeln('## 네트워크 상태');
      final network = diagnostics['network'] as Map<String, dynamic>;
      buffer.writeln('- 인터넷 연결: ${network['internetConnection'] == true ? '✅' : '❌'}');
      if (network.containsKey('apiServerReachable')) {
        buffer.writeln('- API 서버 접근: ${network['apiServerReachable'] == true ? '✅' : '❌'}');
      }
      buffer.writeln();
    }
    
    // API 엔드포인트
    if (diagnostics.containsKey('apiEndpoint')) {
      buffer.writeln('## API 엔드포인트');
      final api = diagnostics['apiEndpoint'] as Map<String, dynamic>;
      if (api['skip'] == true) {
        buffer.writeln('- Mock 모드로 건너뜀');
      } else {
        buffer.writeln('- CORS 활성화: ${api['corsEnabled'] == true ? '✅' : '❌'}');
        buffer.writeln('- 로그인 엔드포인트 상태: ${api['loginEndpointStatus']}');
        if (api.containsKey('responseKeys')) {
          buffer.writeln('- 응답 키: ${api['responseKeys']}');
        }
      }
      buffer.writeln();
    }
    
    // 직렬화 테스트
    if (diagnostics.containsKey('serialization')) {
      buffer.writeln('## 모델 직렬화');
      final serial = diagnostics['serialization'] as Map<String, dynamic>;
      buffer.writeln('- LoginRequest: ${serial['loginRequestValid'] == true ? '✅' : '❌'}');
      buffer.writeln('- 응답 형식 1: ${serial['format1Valid'] == true ? '✅' : '❌'}');
      buffer.writeln('- 응답 형식 2: ${serial['format2Valid'] == true ? '✅' : '❌'}');
      buffer.writeln();
    }
    
    // 오류 정보
    if (diagnostics.containsKey('error')) {
      buffer.writeln('## ⚠️ 오류 발생');
      buffer.writeln(diagnostics['error']);
    }
    
    return buffer.toString();
  }
}