import 'package:dio/dio.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import '../config/api_config.dart';
import '../services/auth_service.dart';
import '../screens/auth/login_screen.dart';
import '../main.dart'; // navigatorKey를 사용하기 위한 import

class ApiService {
  static final ApiService _instance = ApiService._internal();
  factory ApiService() => _instance;
  
  late Dio _dio;
  final CookieJar _cookieJar = CookieJar();
  
  
  ApiService._internal() {
    _dio = Dio(BaseOptions(
      baseUrl: ApiConfig.baseUrl,
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 10),
      contentType: 'application/json',
    ));
    
    // 쿠키 관리자 설정 (웹 환경에서는 사용하지 않음)
    if (!kIsWeb) {
      _dio.interceptors.add(CookieManager(_cookieJar));
    }
    
    // 로그 인터셉터 (디버깅용)
    _dio.interceptors.add(LogInterceptor(
      requestBody: true,
      responseBody: true,
    ));
  }
  
  // 테스트를 위한 Dio 주입 지점
  @visibleForTesting
  void setDio(Dio dio) {
    _dio = dio;
  }
  
  // 토큰 설정
  void setToken(String token) {
    _dio.options.headers['Authorization'] = 'Bearer $token';
  }
  
  // GET 요청
  Future<dynamic> get(String path, {Map<String, dynamic>? queryParameters}) async {
    try {
      final response = await _dio.get(
        path,
        queryParameters: queryParameters,
      );
      return response.data;
    } on DioException catch (e) {
      _handleError(e);
      rethrow;
    }
  }
  
  // POST 요청
  Future<dynamic> post(String path, {dynamic data}) async {
    try {
      final isForm = data is FormData;
      final response = await _dio.post(
        path,
        data: data ?? {},
        options: isForm ? Options(contentType: 'multipart/form-data') : null,
      );
      return response.data;
    } on DioException catch (e) {
      _handleError(e);
      rethrow;
    }
  }
  
  // PUT 요청
  Future<dynamic> put(String path, {dynamic data}) async {
    try {
      final response = await _dio.put(
        path,
        data: data,
      );
      return response.data;
    } on DioException catch (e) {
      _handleError(e);
      rethrow;
    }
  }
  
  // DELETE 요청
  Future<dynamic> delete(String path) async {
    try {
      final response = await _dio.delete(path);
      return response.data;
    } on DioException catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  // DELETE 요청 (body 데이터 포함이 필요한 경우 사용)
  Future<dynamic> deleteWithData(String path, {dynamic data}) async {
    try {
      final response = await _dio.delete(path, data: data);
      return response.data;
    } on DioException catch (e) {
      _handleError(e);
      rethrow;
    }
  }
  
  // 에러 처리
  void _handleError(DioException e) {
    if (e.response != null) {
      final status = e.response?.statusCode;
      final dataStr = e.response?.data?.toString() ?? '';

      // 초기 진입 등에서 발생 가능한 EXPECTED 400은 콘솔에 노이즈로 찍지 않음
      // 예: { error: '클럽 정보가 필요합니다.' }
      if (status == 400 && (dataStr.contains('클럽 정보가 필요합니다') || dataStr.contains('club'))) {
        // 무음 처리: 상위 호출부에서 사용자 경험을 고려해 처리함
        return;
      }

      print('API 에러: $status - ${e.response?.data}');

      // 401 오류 (인증 실패) 처리
      if (status == 401) {
        print('인증 오류: 토큰이 유효하지 않습니다. 로그아웃 처리합니다.');
        _handleUnauthorized();
      }
    } else {
      print('API 요청 에러: ${e.message}');
    }
  }
  
  // 인증 오류 처리 (401)
  void _handleUnauthorized() {
    // 다음 프레임에서 실행하여 현재 API 호출 스택이 완료되도록 함
    Future.microtask(() async {
      try {
        // AuthService 인스턴스 가져오기
        final authService = AuthService();
        
        // 로그아웃 처리
        await authService.logout();
        
        // 전역 네비게이터 키를 사용하여 로그인 화면으로 이동
        if (navigatorKey.currentContext != null) {
          Navigator.of(navigatorKey.currentContext!).pushAndRemoveUntil(
            MaterialPageRoute(builder: (context) => const LoginScreen()),
            (route) => false,
          );
        }
      } catch (e) {
        print('로그아웃 처리 중 오류 발생: $e');
      }
    });
  }
}
