import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/user/user_dto.dart';

/// 사용자 원격 데이터 소스 (서버 API v0.2.1 대응)
/// 엔드포인트: /api/v1/users
abstract class UserRemoteDataSource {
  /// 사용자 목록 조회 (페이지네이션 지원)
  Future<UserListResponse> getUsers({
    int page = 1,
    int perPage = 20,
    bool? isActive,
    String? role,
  });
  
  /// 단일 사용자 조회
  Future<UserDto> getUser(int id);
  
  /// 사용자 생성
  Future<UserDto> createUser(UserRequestDto request);
  
  /// 사용자 정보 수정 (비밀번호 포함)
  Future<UserDto> updateUser(int id, UserUpdateRequestDto request);
  
  /// 사용자 소프트 삭제 (is_active = false)
  Future<void> deleteUser(int id);
  
}

@LazySingleton(as: UserRemoteDataSource)
class UserRemoteDataSourceImpl implements UserRemoteDataSource {
  final ApiClient _apiClient;

  UserRemoteDataSourceImpl(this._apiClient);

  /// 사용자 목록 조회 (실제 백엔드 API 응답 대응)
  @override
  Future<UserListResponse> getUsers({
    int page = 1,
    int perPage = 20,
    bool? isActive,
    String? role,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'per_page': perPage,
      };
      
      // UI 호환 파라미터 (백엔드에서 무시)
      if (isActive != null) {
        queryParams['is_active'] = isActive;
      }
      if (role != null) {
        queryParams['role'] = role;
      }

      final response = await _apiClient.get(
        '/users',
        queryParameters: queryParams,
      );

      // 실제 백엔드 응답 구조: {data: [...], total: 100, page: 1, page_size: 20, total_pages: 5}
      if (response.data != null) {
        return UserListResponse.fromJson(Map<String, dynamic>.from(response.data));
      } else {
        throw ApiException(
          message: '사용자 목록을 불러오는데 실패했습니다',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.response?.data?['message'] ?? 
                 e.message ?? 
                 '사용자 목록을 불러오는데 실패했습니다',
        statusCode: e.response?.statusCode,
      );
    }
  }

  /// 단일 사용자 조회 (GET /api/v1/users/{id})
  @override
  Future<UserDto> getUser(int id) async {
    try {
      final response = await _apiClient.get('/users/$id');
      
      if (response.data != null) {
        // 실제 백엔드 응답이 단일 객체인 경우
        return UserDto.fromJson(Map<String, dynamic>.from(response.data));
      } else {
        throw ApiException(
          message: '사용자 정보를 불러오는데 실패했습니다',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.response?.data?['message'] ?? 
                 e.message ?? 
                 '사용자 정보를 불러오는데 실패했습니다',
        statusCode: e.response?.statusCode,
      );
    }
  }

  /// 사용자 생성 (POST /api/v1/users)
  @override
  Future<UserDto> createUser(UserRequestDto request) async {
    try {
      final response = await _apiClient.post(
        '/users',
        data: request.toJson(),
      );

      if (response.data != null) {
        return UserDto.fromJson(Map<String, dynamic>.from(response.data));
      } else {
        throw ApiException(
          message: '사용자 생성에 실패했습니다',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.response?.data?['message'] ?? 
                 e.message ?? 
                 '사용자 생성에 실패했습니다',
        statusCode: e.response?.statusCode,
      );
    }
  }

  /// 사용자 수정 (PUT /api/v1/users/{id})
  @override
  Future<UserDto> updateUser(int id, UserUpdateRequestDto request) async {
    try {
      // null이나 빈 값 필터링하여 실제로 변경된 필드만 전송
      final requestData = request.toJson();
      requestData.removeWhere((key, value) => value == null || 
                                              (value is String && value.isEmpty));
      
      final response = await _apiClient.put(
        '/users/$id',
        data: requestData,
      );

      if (response.data != null) {
        return UserDto.fromJson(Map<String, dynamic>.from(response.data));
      } else {
        throw ApiException(
          message: '사용자 정보 수정에 실패했습니다',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.response?.data?['message'] ?? 
                 e.message ?? 
                 '사용자 정보 수정에 실패했습니다',
        statusCode: e.response?.statusCode,
      );
    }
  }

  /// 사용자 소프트 삭제 (DELETE /api/v1/users/{id})
  /// 서버에서 is_active = false로 설정
  @override
  Future<void> deleteUser(int id) async {
    try {
      final response = await _apiClient.delete('/users/$id');
      
      // 소프트 딜리트는 응답 데이터가 있을 수 있음
      if (response.statusCode != null && response.statusCode! >= 400) {
        throw ApiException(
          message: response.data?['message'] ?? '사용자 삭제에 실패했습니다',
          statusCode: response.statusCode,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.response?.data?['message'] ?? 
                 e.message ?? 
                 '사용자 삭제에 실패했습니다',
        statusCode: e.response?.statusCode,
      );
    }
  }

}