import 'dart:convert';
import 'dart:developer' as developer;
import 'package:flutter/foundation.dart';

/// 디버깅을 위한 고급 로거 클래스
class DebugLogger {
  static const String _separator = '=================================================='; // 50개의 '='
  
  /// 디버그 모드에서만 로그 출력
  static void log(
    String message, {
    String? tag,
    Object? data,
    StackTrace? stackTrace,
    bool isError = false,
  }) {
    if (!kDebugMode) return;
    
    final timestamp = DateTime.now().toIso8601String();
    final logTag = tag ?? 'DEBUG';
    
    developer.log(
      '''
$_separator
[$logTag] $timestamp
$message
${data != null ? '\nData: ${_formatData(data)}' : ''}
${stackTrace != null ? '\nStackTrace:\n$stackTrace' : ''}
$_separator
''',
      name: logTag,
      error: isError ? data : null,
      stackTrace: isError ? stackTrace : null,
      time: DateTime.now(),
    );
  }

  /// API 요청 로깅
  static void logApiRequest({
    required String method,
    required String url,
    Map<String, dynamic>? headers,
    dynamic data,
  }) {
    log(
      'API 요청',
      tag: 'API_REQUEST',
      data: {
        'method': method,
        'url': url,
        'headers': headers,
        'data': data,
      },
    );
  }

  /// API 응답 로깅
  static void logApiResponse({
    required String url,
    required int? statusCode,
    Map<String, dynamic>? headers,
    dynamic data,
  }) {
    log(
      'API 응답',
      tag: 'API_RESPONSE',
      data: {
        'url': url,
        'statusCode': statusCode,
        'headers': headers,
        'data': data,
      },
    );
  }

  /// 에러 로깅
  static void logError(
    String message, {
    Object? error,
    StackTrace? stackTrace,
    Map<String, dynamic>? additionalData,
  }) {
    log(
      '에러 발생: $message',
      tag: 'ERROR',
      data: {
        'error': error?.toString(),
        'additionalData': additionalData,
      },
      stackTrace: stackTrace,
      isError: true,
    );
  }

  /// 로그인 프로세스 전용 로깅
  static void logLogin(String step, {Map<String, dynamic>? data}) {
    log(
      '로그인 프로세스: $step',
      tag: 'LOGIN',
      data: data,
    );
  }

  /// 데이터 포맷팅
  static String _formatData(Object data) {
    try {
      if (data is Map || data is List) {
        return const JsonEncoder.withIndent('  ').convert(data);
      }
      return data.toString();
    } catch (e) {
      return data.toString();
    }
  }

  /// 디버그 모드 확인
  static bool get isDebugMode => kDebugMode;

  /// Assert를 사용한 런타임 검증 (디버그 모드에서만)
  static void assertValid(
    bool condition,
    String message, {
    Map<String, dynamic>? data,
  }) {
    assert(() {
      if (!condition) {
        logError('Assertion failed: $message', additionalData: data);
      }
      return condition;
    }(), message);
  }

  /// JSON 파싱 검증 및 로깅
  static T? parseJsonWithLogging<T>(
    dynamic json,
    T Function(Map<String, dynamic>) parser, {
    required String objectName,
  }) {
    try {
      if (json == null) {
        logError('$objectName 파싱 실패: JSON이 null입니다');
        return null;
      }

      if (json is! Map<String, dynamic>) {
        logError(
          '$objectName 파싱 실패: 잘못된 JSON 형식',
          additionalData: {
            'actualType': json.runtimeType.toString(),
            'expectedType': 'Map<String, dynamic>',
          },
        );
        return null;
      }

      log(
        '$objectName 파싱 시작',
        tag: 'JSON_PARSE',
        data: json,
      );

      final result = parser(json);
      
      log(
        '$objectName 파싱 성공',
        tag: 'JSON_PARSE',
      );

      return result;
    } catch (e, stackTrace) {
      logError(
        '$objectName 파싱 중 예외 발생',
        error: e,
        stackTrace: stackTrace,
        additionalData: {
          'json': json,
        },
      );
      return null;
    }
  }

  /// 응답 데이터 구조 검증
  static bool validateResponseStructure(
    Map<String, dynamic> response,
    List<String> requiredFields, {
    String? responseName,
  }) {
    final missing = <String>[];
    
    for (final field in requiredFields) {
      if (!response.containsKey(field)) {
        missing.add(field);
      }
    }

    if (missing.isNotEmpty) {
      logError(
        '${responseName ?? 'Response'} 구조 검증 실패',
        additionalData: {
          'missingFields': missing,
          'actualFields': response.keys.toList(),
        },
      );
      return false;
    }

    log(
      '${responseName ?? 'Response'} 구조 검증 성공',
      tag: 'VALIDATION',
    );
    return true;
  }
}