import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/maintenance_dto.dart';

abstract class MaintenanceRemoteDataSource {
  Future<MaintenanceListResponse> getMaintenances({
    int page = 1,
    int perPage = 20,
    int? equipmentId,
    String? maintenanceType,
    bool? isExpired,
    int? expiringDays,
    bool includeDeleted = false,
  });
  
  Future<MaintenanceDto> createMaintenance(MaintenanceRequestDto request);
  
  Future<MaintenanceDto> getMaintenanceDetail(int id);
  
  Future<MaintenanceDto> updateMaintenance(int id, MaintenanceUpdateRequestDto request);
  
  Future<void> deleteMaintenance(int id);
  
  // 만료 예정 유지보수 조회 (백엔드 전용 API)
  Future<List<MaintenanceDto>> getExpiringMaintenances({int days = 30});
}

class MaintenanceRemoteDataSourceImpl implements MaintenanceRemoteDataSource {
  final ApiClient _apiClient = GetIt.instance<ApiClient>();

  @override
  Future<MaintenanceListResponse> getMaintenances({
    int page = 1,
    int perPage = 20,
    int? equipmentId,
    String? maintenanceType,
    bool? isExpired,
    int? expiringDays,
    bool includeDeleted = false,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'per_page': perPage,
        if (equipmentId != null) 'equipment_id': equipmentId,
        if (maintenanceType != null) 'maintenance_type': maintenanceType,
        if (isExpired != null) 'is_expired': isExpired,
        if (expiringDays != null) 'expiring_days': expiringDays,
        'include_deleted': includeDeleted,
      };

      final response = await _apiClient.get(
        ApiEndpoints.maintenances,
        queryParameters: queryParams,
      );

      print('[Maintenance API] Response: ${response.data}');

      // 백엔드 응답은 직접 data 배열과 페이지네이션 정보 반환
      final Map<String, dynamic> responseData = response.data;
      return MaintenanceListResponse.fromJson(responseData);
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }

  @override
  Future<MaintenanceDto> createMaintenance(MaintenanceRequestDto request) async {
    try {
      final response = await _apiClient.post(
        ApiEndpoints.maintenances,
        data: request.toJson(),
      );

      print('[Maintenance API] Create Response: ${response.data}');
      
      // API 응답이 {success: true, data: {...}} 형태인 경우 처리
      final responseData = response.data;
      if (responseData is Map && responseData.containsKey('data')) {
        return MaintenanceDto.fromJson(responseData['data']);
      } else {
        // 직접 데이터인 경우
        return MaintenanceDto.fromJson(responseData);
      }
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }

  @override
  Future<MaintenanceDto> getMaintenanceDetail(int id) async {
    try {
      final response = await _apiClient.get('${ApiEndpoints.maintenances}/$id');

      print('[Maintenance API] Detail Response: ${response.data}');
      
      // API 응답이 {success: true, data: {...}} 형태인 경우 처리
      final responseData = response.data;
      if (responseData is Map && responseData.containsKey('data')) {
        return MaintenanceDto.fromJson(responseData['data']);
      } else {
        // 직접 데이터인 경우
        return MaintenanceDto.fromJson(responseData);
      }
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }

  @override
  Future<MaintenanceDto> updateMaintenance(int id, MaintenanceUpdateRequestDto request) async {
    try {
      // 디버그: 전송할 JSON 데이터 로깅
      final jsonData = request.toJson();
      
      // null 필드 제거 (백엔드가 null을 처리하지 못하는 경우 대비)
      final cleanedData = Map<String, dynamic>.from(jsonData)
        ..removeWhere((key, value) => value == null);
      
      print('[Maintenance API] Update Request JSON: $cleanedData');
      print('[Maintenance API] JSON keys: ${cleanedData.keys.toList()}');
      
      final response = await _apiClient.put(
        '${ApiEndpoints.maintenances}/$id',
        data: cleanedData,
      );

      print('[Maintenance API] Update Response: ${response.data}');
      
      // API 응답이 {success: true, data: {...}} 형태인 경우 처리
      final responseData = response.data;
      if (responseData is Map && responseData.containsKey('data')) {
        return MaintenanceDto.fromJson(responseData['data']);
      } else {
        // 직접 데이터인 경우
        return MaintenanceDto.fromJson(responseData);
      }
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }

  @override
  Future<void> deleteMaintenance(int id) async {
    try {
      await _apiClient.delete('${ApiEndpoints.maintenances}/$id');
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }

  @override
  Future<List<MaintenanceDto>> getExpiringMaintenances({int days = 30}) async {
    try {
      final response = await _apiClient.get(
        '${ApiEndpoints.maintenances}/expiring',
        queryParameters: {'days': days},
      );

      print('[Maintenance API] Expiring Response: ${response.data}');
      
      // 백엔드는 직접 배열을 반환
      final List<dynamic> responseData = response.data;
      return responseData.map((json) => MaintenanceDto.fromJson(json)).toList();
    } on DioException catch (e) {
      throw ServerException(
        message: e.response?.data['message'] ?? 'Network error occurred',
        statusCode: e.response?.statusCode,
      );
    }
  }
}