import 'package:dio/dio.dart';
import '../../core/error/exceptions.dart';
import '../../core/network/api_client.dart';
import '../dto/advance_request_dto.dart';
import '../dto/advance_response_dto.dart';
import '../dto/advances_list_response_dto.dart';

abstract class AdvanceRemoteDataSource {
  Future<AdvanceResponseDto> createAdvance(AdvanceRequestDto request);
  Future<AdvancesListResponseDto> getAdvances();
}

class AdvanceRemoteDataSourceImpl implements AdvanceRemoteDataSource {
  final ApiClient apiClient;

  AdvanceRemoteDataSourceImpl({required this.apiClient});

  @override
  Future<AdvanceResponseDto> createAdvance(AdvanceRequestDto request) async {
    try {
      final response = await apiClient.post(
        '/SalaryInAdvance',
        data: request.toJson(),
      );

      if (response.statusCode == 200 || response.statusCode == 201) {
        final responseData = response.data;

        if (responseData is Map<String, dynamic>) {
          return AdvanceResponseDto.fromJson(responseData);
        } else {
          throw ServerException(
            message: 'استجابة غير صحيحة من الخادم',
            statusCode: response.statusCode,
          );
        }
      } else {
        throw ServerException(
          message: 'فشل إنشاء طلب السلفة',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      if (e.type == DioExceptionType.connectionTimeout ||
          e.type == DioExceptionType.receiveTimeout) {
        throw NetworkException(message: 'انتهت مهلة الاتصال');
      } else if (e.type == DioExceptionType.connectionError) {
        throw NetworkException(message: 'لا يوجد اتصال بالانترنيت');
      } else if (e.response?.statusCode == 500) {
        throw ServerException(message: 'خطأ في الخادم يرجى المحاولة لاحقا');
      } else if (e.response != null) {
        final message =
            e.response?.data?['message'] ??
            e.response?.data?['error'] ??
            'فشل إنشاء طلب السلفة';

        throw ServerException(
          message: message.toString(),
          statusCode: e.response?.statusCode,
        );
      } else {
        throw NetworkException(message: 'خطأ في الانترنيت يرجى المحاولة لاحقا');
      }
    } catch (e) {
      if (e is ServerException || e is NetworkException) {
        rethrow;
      }
      print('خطأ غير متوقع: $e');
      throw ServerException(message: 'خطأ غير متوقع');
    }
  }

  @override
  Future<AdvancesListResponseDto> getAdvances() async {
    try {
      final response = await apiClient.get('/SalaryInAdvance');

      if (response.statusCode == 200) {
        final responseData = response.data;

        if (responseData is Map<String, dynamic>) {
          return AdvancesListResponseDto.fromJson(responseData);
        } else {
          throw ServerException(
            message: 'استجابة غير صحيحة من الخادم',
            statusCode: response.statusCode,
          );
        }
      } else {
        throw ServerException(
          message: 'فشل جلب قائمة السلف',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      if (e.type == DioExceptionType.connectionTimeout ||
          e.type == DioExceptionType.receiveTimeout) {
        throw NetworkException(message: 'انتهت مهلة الاتصال');
      } else if (e.type == DioExceptionType.connectionError) {
        throw NetworkException(message: 'لا يوجد اتصال بالانترنيت');
      } else if (e.response?.statusCode == 500) {
        throw ServerException(message: 'خطأ في الخادم يرجى المحاولة لاحقا');
      } else if (e.response != null) {
        final message =
            e.response?.data?['message'] ??
            e.response?.data?['error'] ??
            'فشل جلب قائمة السلف';

        throw ServerException(
          message: message.toString(),
          statusCode: e.response?.statusCode,
        );
      } else {
        throw NetworkException(message: 'خطأ في الانترنيت يرجى المحاولة لاحقا');
      }
    } catch (e) {
      if (e is ServerException || e is NetworkException) {
        rethrow;
      }
      print('خطأ غير متوقع: $e');
      throw ServerException(message: 'خطأ غير متوقع');
    }
  }
}
