import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:qyuota/config/api_config.dart';
import 'package:qyuota/services/auth_service.dart';
import 'package:qyuota/models/leave.dart';

class ApiService {
  final AuthService _authService = AuthService();

  Future<Map<String, dynamic>> get(String endpoint) async {
    try {
      final token = await _authService.getToken();
      if (token == null) {
        throw Exception('Token not found. Please login again.');
      }

      final response = await http.get(
        Uri.parse('${ApiConfig.baseUrl}$endpoint'),
        headers: ApiConfig.authHeaders(token),
      );

      return _handleResponse(response);
    } catch (e) {
      throw Exception('Failed to make GET request: $e');
    }
  }

  Future<Map<String, dynamic>> post(
      String endpoint, Map<String, dynamic> body) async {
    try {
      final token = await _authService.getToken();
      if (token == null) {
        throw Exception('Token not found. Please login again.');
      }

      final response = await http.post(
        Uri.parse('${ApiConfig.baseUrl}$endpoint'),
        headers: ApiConfig.authHeaders(token),
        body: jsonEncode(body),
      );

      return _handleResponse(response);
    } catch (e) {
      throw Exception('Failed to make POST request: $e');
    }
  }

  Map<String, dynamic> _handleResponse(http.Response response) {
    final responseData = jsonDecode(response.body);
    
    if (response.statusCode >= 200 && response.statusCode < 300) {
      return responseData;
    } else {
      throw Exception(responseData['message'] ?? 'Request failed');
    }
  }

  // Contoh penggunaan untuk fitur cuti
  Future<List<Map<String, dynamic>>> getCutiList() async {
    final response = await get('${ApiConfig.cuti}/list');
    return List<Map<String, dynamic>>.from(response['data']);
  }

  Future<Map<String, dynamic>> submitCuti(Map<String, dynamic> cutiData) async {
    return await post(ApiConfig.cuti, cutiData);
  }

  // Contoh penggunaan untuk fitur absensi
  Future<List<Map<String, dynamic>>> getAbsensiList() async {
    final response = await get('${ApiConfig.absensi}/list');
    return List<Map<String, dynamic>>.from(response['data']);
  }

  Future<Map<String, dynamic>> submitAbsensi(
      Map<String, dynamic> absensiData) async {
    return await post(ApiConfig.absensi, absensiData);
  }

  static Future<Map<String, dynamic>> multipartRequest(
    String url,
    String method,
    Map<String, String> fields,
    Map<String, File> files,
    String? token,
  ) async {
    try {
      final request = http.MultipartRequest(method, Uri.parse(url));
      
      if (token != null) {
        request.headers.addAll({
          'Authorization': 'Bearer $token',
          'Accept': 'application/json',
        });
      }

      // Add fields
      request.fields.addAll(fields);

      // Add files
      for (var entry in files.entries) {
        final file = await http.MultipartFile.fromPath(
          entry.key,
          entry.value.path,
        );
        request.files.add(file);
      }

      final streamedResponse = await request.send();
      final response = await http.Response.fromStream(streamedResponse);

      if (response.statusCode == 200 || response.statusCode == 201) {
        return jsonDecode(response.body);
      } else {
        throw Exception('Multipart request failed: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('Multipart request failed: $e');
    }
  }

  Future<List<Leave>> getLeaves() async {
    try {
      final token = await AuthService().getToken();
      final userId = await AuthService().getUserId();
      
      if (token == null || userId == null) {
        throw Exception('Token atau User ID tidak ditemukan');
      }

      final queryParameters = {'user_id': userId};
      final uri = Uri.parse(ApiConfig.cuti).replace(queryParameters: queryParameters);
      
      // Debug logs
      print('Fetching leaves for user_id: $userId');
      print('Request URL: $uri');
      
      final response = await http.get(
        uri,
        headers: ApiConfig.authHeaders(token),
      );

      // Debug response
      print('Response status code: ${response.statusCode}');
      print('Response body: ${response.body}');

      if (response.statusCode == 200) {
        final Map<String, dynamic> jsonResponse = json.decode(response.body);
        
        if (jsonResponse['data'] != null) {
          List<dynamic> data = jsonResponse['data'];
          final leaves = data.map((item) => Leave.fromJson(item)).toList();
          
          // Sort leaves by date (newest first)
          leaves.sort((a, b) {
            if (a.startDate == null || b.startDate == null) return 0;
            return DateTime.parse(b.startDate).compareTo(DateTime.parse(a.startDate));
          });
          
          return leaves;
        } else {
          return [];
        }
      } else if (response.statusCode == 401) {
        throw Exception('Sesi telah berakhir, silakan login kembali');
      } else if (response.statusCode == 403) {
        // Handle forbidden response (no permission to view these leaves)
        print('Received 403 from server: User doesn\'t have permission to view these leaves');
        return []; // Return empty list instead of failing
      } else {
        final errorBody = json.decode(response.body);
        final errorMessage = errorBody['message'] ?? 'Gagal memuat data cuti';
        throw Exception(errorMessage);
      }
    } catch (e) {
      if (e is FormatException) {
        throw Exception('Format data tidak valid');
      }
      rethrow;
    }
  }
}
