import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';

class ApiService {
  static const String baseUrl = 'http://localhost:3000/api';
  static const String tokenKey = 'auth_token';
  
  late Dio _dio;
  
  ApiService() {
    _dio = Dio(BaseOptions(
      baseUrl: baseUrl,
      connectTimeout: const Duration(seconds: 30),
      receiveTimeout: const Duration(seconds: 30),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    ));
    
    // Add interceptor to include auth token
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        final token = await _getToken();
        if (token != null) {
          options.headers['Authorization'] = 'Bearer $token';
        }
        handler.next(options);
      },
      onError: (error, handler) {
        if (error.response?.statusCode == 401) {
          // Token expired or invalid
          _clearToken();
        }
        handler.next(error);
      },
    ));
  }

  // Token management
  Future<String?> _getToken() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(tokenKey);
  }

  Future<void> _saveToken(String token) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(tokenKey, token);
  }

  Future<void> _clearToken() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(tokenKey);
  }

  // Authentication APIs
  Future<Map<String, dynamic>> login(String mobileNumber, String password) async {
    try {
      final response = await _dio.post('/auth/login', data: {
        'mobile_number': mobileNumber,
        'password': password,
      });
      
      if (response.data['success']) {
        await _saveToken(response.data['data']['token']);
      }
      
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getProfile() async {
    try {
      final response = await _dio.get('/auth/profile');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> updateProfile(Map<String, dynamic> data) async {
    try {
      final response = await _dio.put('/auth/profile', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> changePassword(String currentPassword, String newPassword) async {
    try {
      final response = await _dio.put('/auth/change-password', data: {
        'current_password': currentPassword,
        'new_password': newPassword,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> createMember(String mobileNumber, String fullName, {String? email, String? address, String? emergencyContact}) async {
    try {
      final data = {
        'mobile_number': mobileNumber,
        'full_name': fullName,
      };
      
      if (email != null && email.isNotEmpty) data['email'] = email;
      if (address != null && address.isNotEmpty) data['address'] = address;
      if (emergencyContact != null && emergencyContact.isNotEmpty) data['emergency_contact'] = emergencyContact;
      
      final response = await _dio.post('/auth/create-member', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Chit Group APIs
  Future<Map<String, dynamic>> createChitGroup(Map<String, dynamic> data) async {
    try {
      final response = await _dio.post('/chit-groups', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getManagerChitGroups({String? status, int page = 1, int limit = 10}) async {
    try {
      final response = await _dio.get('/chit-groups/manager', queryParameters: {
        if (status != null) 'status': status,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getMemberChitGroups({String? status, int page = 1, int limit = 10}) async {
    try {
      final response = await _dio.get('/chit-groups/member', queryParameters: {
        if (status != null) 'status': status,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getChitGroupDetails(String groupId) async {
    try {
      final response = await _dio.get('/chit-groups/$groupId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> updateChitGroup(String groupId, Map<String, dynamic> data) async {
    try {
      final response = await _dio.put('/chit-groups/$groupId', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> deleteChitGroup(String groupId) async {
    try {
      final response = await _dio.delete('/chit-groups/$groupId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> startChitGroup(String groupId) async {
    try {
      final response = await _dio.post('/chit-groups/$groupId/start');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getChitGroupStats(String groupId) async {
    try {
      final response = await _dio.get('/chit-groups/$groupId/stats');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Member Management APIs
  Future<Map<String, dynamic>> addMemberToGroup(String groupId, Map<String, dynamic> memberData) async {
    try {
      final response = await _dio.post('/members/$groupId/members', data: memberData);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> removeMemberFromGroup(String groupId, String memberId) async {
    try {
      final response = await _dio.delete('/members/$groupId/members/$memberId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getAllUsers({String? search, int page = 1, int limit = 50}) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'limit': limit,
      };

      if (search != null && search.isNotEmpty) {
        queryParams['search'] = search;
      }

      final response = await _dio.get('/members/users', queryParameters: queryParams);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getAvailableUsersForGroup(String groupId) async {
    try {
      final response = await _dio.get('/members/users/available/$groupId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getGroupMembers(String groupId, {String? status, int page = 1, int limit = 20}) async {
    try {
      final response = await _dio.get('/members/$groupId/members', queryParameters: {
        if (status != null) 'status': status,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getMemberDetails(String groupId, String memberId) async {
    try {
      final response = await _dio.get('/members/$groupId/members/$memberId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> updateMemberStatus(String groupId, String memberId, String status) async {
    try {
      final response = await _dio.put('/members/$groupId/members/$memberId/status', data: {
        'status': status,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getMemberPaymentSummary(String groupId, String memberId) async {
    try {
      final response = await _dio.get('/members/$groupId/members/$memberId/payment-summary');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Payment Management APIs
  Future<Map<String, dynamic>> recordPayment(Map<String, dynamic> data) async {
    try {
      final response = await _dio.post('/payments', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getGroupPayments(String groupId, {String? status, int? month, int? year, int page = 1, int limit = 20}) async {
    try {
      final response = await _dio.get('/payments/group/$groupId', queryParameters: {
        if (status != null) 'status': status,
        if (month != null) 'month': month,
        if (year != null) 'year': year,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getMemberPayments(String groupId, String memberId, {String? status, int page = 1, int limit = 20}) async {
    try {
      final response = await _dio.get('/payments/group/$groupId/member/$memberId', queryParameters: {
        if (status != null) 'status': status,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> updatePaymentStatus(String paymentId, String status, {String? notes}) async {
    try {
      final response = await _dio.put('/payments/$paymentId/status', data: {
        'status': status,
        if (notes != null) 'notes': notes,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getGroupPaymentSummary(String groupId) async {
    try {
      final response = await _dio.get('/payments/group/$groupId/summary');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getPendingPayments(String groupId) async {
    try {
      final response = await _dio.get('/payments/group/$groupId/pending');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Monthly Draw APIs
  Future<Map<String, dynamic>> createMonthlyDraw(Map<String, dynamic> data) async {
    try {
      final response = await _dio.post('/monthly-draws', data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getGroupMonthlyDraws(String groupId, {String? status, int page = 1, int limit = 20}) async {
    try {
      final response = await _dio.get('/monthly-draws/group/$groupId', queryParameters: {
        if (status != null) 'status': status,
        'page': page,
        'limit': limit,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getMonthlyDrawDetails(String drawId) async {
    try {
      final response = await _dio.get('/monthly-draws/$drawId');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> verifyDrawResult(String drawId, {String? clientSeed}) async {
    try {
      final response = await _dio.post('/monthly-draws/$drawId/verify', data: {
        if (clientSeed != null) 'client_seed': clientSeed,
      });
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getDrawStatistics(String groupId) async {
    try {
      final response = await _dio.get('/monthly-draws/group/$groupId/statistics');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> getGroupFinancialData(String groupId) async {
    try {
      final response = await _dio.get('/chit-groups/$groupId/financial-data');
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Generic HTTP Methods
  Future<Map<String, 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) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> post(String path, Map<String, dynamic> data) async {
    try {
      final response = await _dio.post(path, data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> put(String path, Map<String, dynamic> data) async {
    try {
      final response = await _dio.put(path, data: data);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  Future<Map<String, dynamic>> delete(String path) async {
    try {
      final response = await _dio.delete(path);
      return response.data;
    } on DioException catch (e) {
      return _handleError(e);
    }
  }

  // Logout
  Future<void> logout() async {
    await _clearToken();
  }

  // Error handling
  Map<String, dynamic> _handleError(DioException e) {
    if (e.response != null) {
      final responseData = e.response?.data;
      String message = 'Request failed';
      
      if (responseData is Map<String, dynamic>) {
        message = responseData['message']?.toString() ?? 'Request failed';
      } else if (responseData is String) {
        message = responseData;
      }
      
      return {
        'success': false,
        'message': message,
        'statusCode': e.response?.statusCode,
      };
    } else {
      return {
        'success': false,
        'message': 'Network error: ${e.message}',
        'statusCode': 0,
      };
    }
  }
}
