import 'package:flutter_test/flutter_test.dart';
import 'package:dio/dio.dart';
import 'package:lanebow/services/api_service.dart';

class _FakeBackendInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    final path = options.path;
    // 성공 케이스
    if (path == '/ping' && options.method == 'GET') {
      return handler.resolve(Response(
        requestOptions: options,
        statusCode: 200,
        data: {'ok': true},
      ));
    }
    if (path == '/echo' && options.method == 'POST') {
      return handler.resolve(Response(
        requestOptions: options,
        statusCode: 200,
        data: options.data ?? {},
      ));
    }
    if (path == '/put' && options.method == 'PUT') {
      return handler.resolve(Response(
        requestOptions: options,
        statusCode: 200,
        data: {'updated': true},
      ));
    }
    if (path == '/del' && options.method == 'DELETE') {
      return handler.resolve(Response(
        requestOptions: options,
        statusCode: 200,
        data: {'deleted': true},
      ));
    }

    // 401 에러 케이스
    if (path == '/unauthorized') {
      return handler.reject(DioException(
        requestOptions: options,
        response: Response(requestOptions: options, statusCode: 401, data: {'message': 'unauthorized'}),
        type: DioExceptionType.badResponse,
      ));
    }

    // 기타 500 에러
    return handler.reject(DioException(
      requestOptions: options,
      response: Response(requestOptions: options, statusCode: 500, data: {'message': 'server error'}),
      type: DioExceptionType.badResponse,
    ));
  }
}

void main() {
  group('ApiService', () {
    late ApiService api;
    late Dio dio;

    setUp(() {
      api = ApiService();
      dio = Dio(BaseOptions(baseUrl: 'http://test')); // baseUrl은 테스트에서 의미 없음
      dio.interceptors.clear();
      dio.interceptors.add(_FakeBackendInterceptor());
      api.setDio(dio);
    });

    test('GET 성공 시 data 반환', () async {
      final data = await api.get('/ping');
      expect(data, isA<Map>());
      expect(data['ok'], true);
    });

    test('POST 성공 시 body echo', () async {
      final payload = {'a': 1};
      final data = await api.post('/echo', data: payload);
      expect(data, payload);
    });

    test('PUT 성공 시 updated=true', () async {
      final data = await api.put('/put', data: {'x': 1});
      expect(data['updated'], true);
    });

    test('DELETE 성공 시 deleted=true', () async {
      final data = await api.delete('/del');
      expect(data['deleted'], true);
    });

    test('401 발생 시 DioException rethrow', () async {
      expect(
        () => api.get('/unauthorized'),
        throwsA(isA<DioException>()),
      );
    });

    test('기타 에러(500) 발생 시 DioException rethrow', () async {
      expect(
        () => api.get('/unknown'),
        throwsA(isA<DioException>()),
      );
    });
  });
}
