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/administrator_dto.dart';

/// 관리자 원격 데이터 소스 (백엔드 Administrator 테이블)
/// 엔드포인트: /api/v1/administrators
abstract class AdministratorRemoteDataSource {
  /// 관리자 목록 조회 (페이지네이션 지원)
  Future<AdministratorListResponse> getAdministrators({
    int page = 1,
    int pageSize = 10,
    String? search,
  });
  
  /// 단일 관리자 조회
  Future<AdministratorDto> getAdministrator(int id);
  
  /// 관리자 생성
  Future<AdministratorDto> createAdministrator(AdministratorRequestDto request);
  
  /// 관리자 정보 수정
  Future<AdministratorDto> updateAdministrator(int id, AdministratorUpdateRequestDto request);
  
  /// 관리자 삭제
  Future<void> deleteAdministrator(int id);
  
  /// 이메일 중복 확인
  Future<bool> checkEmailAvailability(String email, {int? excludeId});
  
  /// 관리자 인증 (로그인)
  Future<AdministratorDto> authenticateAdministrator(String email, String password);
}

@LazySingleton(as: AdministratorRemoteDataSource)
class AdministratorRemoteDataSourceImpl implements AdministratorRemoteDataSource {
  final ApiClient _apiClient;

  AdministratorRemoteDataSourceImpl(this._apiClient);

  /// 관리자 목록 조회
  @override
  Future<AdministratorListResponse> getAdministrators({
    int page = 1,
    int pageSize = 10,
    String? search,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'page_size': pageSize,
      };
      
      if (search != null && search.isNotEmpty) {
        queryParams['search'] = search;
      }

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

      if (response.data != null) {
        return AdministratorListResponse.fromJson(response.data);
      } else {
        throw ApiException(
          message: '관리자 목록 조회 응답이 비어있습니다',
          statusCode: response.statusCode ?? 500,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? '관리자 목록 조회 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 목록 조회 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }

  /// 단일 관리자 조회
  @override
  Future<AdministratorDto> getAdministrator(int id) async {
    try {
      final response = await _apiClient.get('/administrators/$id');

      if (response.data != null) {
        return AdministratorDto.fromJson(response.data);
      } else {
        throw ApiException(
          message: '관리자 정보 조회 응답이 비어있습니다',
          statusCode: response.statusCode ?? 500,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? 'API 호출 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 정보 조회 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }

  /// 관리자 생성
  @override
  Future<AdministratorDto> createAdministrator(AdministratorRequestDto request) async {
    try {
      final response = await _apiClient.post(
        '/administrators',
        data: request.toJson(),
      );

      if (response.data != null) {
        return AdministratorDto.fromJson(response.data);
      } else {
        throw ApiException(
          message: '관리자 생성 응답이 비어있습니다',
          statusCode: response.statusCode ?? 500,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? 'API 호출 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 생성 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }

  /// 관리자 정보 수정
  @override
  Future<AdministratorDto> updateAdministrator(int id, AdministratorUpdateRequestDto request) async {
    try {
      final response = await _apiClient.put(
        '/administrators/$id',
        data: request.toJson(),
      );

      if (response.data != null) {
        return AdministratorDto.fromJson(response.data);
      } else {
        throw ApiException(
          message: '관리자 정보 수정 응답이 비어있습니다',
          statusCode: response.statusCode ?? 500,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? 'API 호출 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 정보 수정 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }

  /// 관리자 삭제
  @override
  Future<void> deleteAdministrator(int id) async {
    try {
      await _apiClient.delete('/administrators/$id');
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? 'API 호출 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 삭제 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }

  /// 이메일 중복 확인 (미래에 백엔드에서 지원될 수 있는 기능)
  @override
  Future<bool> checkEmailAvailability(String email, {int? excludeId}) async {
    try {
      // 현재는 단순히 true 반환 (중복되지 않음으로 가정)
      // 실제 백엔드 구현 시 아래와 같이 호출
      /*
      final queryParams = <String, dynamic>{
        'email': email,
        if (excludeId != null) 'exclude_id': excludeId,
      };
      
      final response = await _apiClient.get(
        '/administrators/check-email',
        queryParameters: queryParams,
      );
      
      return response.data['available'] ?? false;
      */
      
      return true; // 임시로 항상 사용 가능으로 반환
    } catch (e) {
      // 에러 발생 시 안전하게 false 반환 (사용 불가로 처리)
      return false;
    }
  }

  /// 관리자 인증 (로그인)
  @override
  Future<AdministratorDto> authenticateAdministrator(String email, String password) async {
    try {
      final response = await _apiClient.post(
        '/auth/login',
        data: {
          'email': email,
          'password': password,
        },
      );

      if (response.data != null && response.data['user'] != null) {
        return AdministratorDto.fromJson(response.data['user']);
      } else if (response.data != null) {
        return AdministratorDto.fromJson(response.data);
      } else {
        throw ApiException(
          message: '로그인 응답이 비어있습니다',
          statusCode: response.statusCode ?? 500,
        );
      }
    } on DioException catch (e) {
      throw ApiException(
        message: e.message ?? 'API 호출 중 오류 발생',
        statusCode: e.response?.statusCode,
      );
    } catch (e) {
      throw ApiException(
        message: '관리자 인증 중 오류 발생: ${e.toString()}',
        statusCode: 500,
      );
    }
  }
}