import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';

abstract class ProfileSettingsRepo {
  /// Updates general patient info (name, phone, etc.).
  Future<Either<Failure, GenericApiModel<dynamic>>> updatePatientInfo({
    required Map<String, dynamic> patientInfo,
  });

  /// Deactivates (deletes) the patient's account.
  Future<Either<Failure, GenericApiModel<dynamic>>> deactivateAccount();

  Future<Either<Failure, GenericApiModel<dynamic>>> getProfileSettings();

  /// Get patient profile image
  Future<Either<Failure, GenericApiModel<dynamic>>> getProfileImage({
    required int patientID,
  });

  /// Upload patient profile image
  Future<Either<Failure, GenericApiModel<dynamic>>> uploadProfileImage({
    required int patientID,
    required String imageData,
    required bool isActive,
  });
}

class ProfileSettingsRepoImp implements ProfileSettingsRepo {
  final ApiClient apiClient;
  final LoggerService loggerService;

  ProfileSettingsRepoImp({
    required this.loggerService,
    required this.apiClient,
  });

  @override
  Future<Either<Failure, GenericApiModel<dynamic>>> updatePatientInfo({
    required Map<String, dynamic> patientInfo,
  }) async {
    try {
      GenericApiModel<dynamic>? apiResponse;
      Failure? failure;

      await apiClient.post(
        SAVE_SETTING,
        body: patientInfo,
        onFailure: (error, statusCode, {messageStatus, failureType}) {
          failure = failureType;
        },
        onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
          try {
            apiResponse = GenericApiModel<dynamic>(
              messageStatus: messageStatus,
              statusCode: statusCode,
              errorMessage: errorMessage,
              data: response,
            );
          } catch (e) {
            failure = DataParsingFailure(e.toString());
          }
        },
      );

      if (failure != null) return Left(failure!);
      if (apiResponse == null) return Left(ServerFailure("Unknown error"));
      return Right(apiResponse!);
    } catch (e) {
      return Left(UnknownFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, GenericApiModel<dynamic>>> deactivateAccount() async {
    final Map<String, dynamic> body = {};

    try {
      GenericApiModel<dynamic>? apiResponse;
      Failure? failure;

      await apiClient.post(
        // TODO: Replace with actual deactivate-account endpoint once available
        'Services/Patients.svc/REST/Patient_DeactivateAccount',
        body: body,
        onFailure: (error, statusCode, {messageStatus, failureType}) {
          failure = failureType;
        },
        onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
          try {
            apiResponse = GenericApiModel<dynamic>(
              messageStatus: messageStatus,
              statusCode: statusCode,
              errorMessage: errorMessage,
              data: response,
            );
          } catch (e) {
            failure = DataParsingFailure(e.toString());
          }
        },
      );

      if (failure != null) return Left(failure!);
      if (apiResponse == null) return Left(ServerFailure("Unknown error"));
      return Right(apiResponse!);
    } catch (e) {
      return Left(UnknownFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, GenericApiModel>> getProfileSettings() async {
    final Map<String, dynamic> body = {};

    try {
      GenericApiModel<GetPatientInfoForUpdate>? apiResponse;
      Failure? failure;

      await apiClient.post(
        PROFILE_SETTING,
        body: body,
        onFailure: (error, statusCode, {messageStatus, failureType}) {
          failure = failureType;
        },
        onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
          try {
            final patientProfileInfo = GetPatientInfoForUpdate.fromJson(response['PateintInfoForUpdateList'][0]);

            apiResponse = GenericApiModel<GetPatientInfoForUpdate>(
              messageStatus: messageStatus,
              statusCode: statusCode,
              errorMessage: errorMessage,
              data: patientProfileInfo,
            );
          } catch (e) {
            failure = DataParsingFailure(e.toString());
          }
        },
      );

      if (failure != null) return Left(failure!);
      if (apiResponse == null) return Left(ServerFailure("Unknown error"));
      return Right(apiResponse!);
    } catch (e) {
      return Left(UnknownFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, GenericApiModel<dynamic>>>   getProfileImage({
    required int patientID,
  }) async {
    final Map<String, dynamic> body = {
      'PatientID': patientID,
    };

    try {
      GenericApiModel<dynamic>? apiResponse;
      Failure? failure;

      await apiClient.post(
        GET_PROFILE_IMAGE,
        body: body,
        onFailure: (error, statusCode, {messageStatus, failureType}) {
          failure = failureType;
        },
        onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
          try {
            apiResponse = GenericApiModel<dynamic>(
              messageStatus: messageStatus,
              statusCode: statusCode,
              errorMessage: errorMessage,
              data: response,
            );
          } catch (e) {
            failure = DataParsingFailure(e.toString());
          }
        },
      );

      if (failure != null) return Left(failure!);
      if (apiResponse == null) return Left(ServerFailure("Unknown error"));
      return Right(apiResponse!);
    } catch (e) {
      return Left(UnknownFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, GenericApiModel<dynamic>>> uploadProfileImage({
    required int patientID,
    required String imageData,
    required bool isActive,
  }) async {
    final Map<String, dynamic> body = {
      'PatientID': patientID,
      'PatientsProfileImageData': imageData,
      'IsActive': isActive,
    };

    try {
      GenericApiModel<dynamic>? apiResponse;
      Failure? failure;

      await apiClient.post(
        UPLOAD_PROFILE_IMAGE,
        body: body,
        onFailure: (error, statusCode, {messageStatus, failureType}) {
          failure = failureType;
        },
        onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
          try {
            apiResponse = GenericApiModel<dynamic>(
              messageStatus: messageStatus,
              statusCode: statusCode,
              errorMessage: errorMessage,
              data: response,
            );
          } catch (e) {
            failure = DataParsingFailure(e.toString());
          }
        },
      );

      if (failure != null) return Left(failure!);
      if (apiResponse == null) return Left(ServerFailure("Unknown error"));
      return Right(apiResponse!);
    } catch (e) {
      return Left(UnknownFailure(e.toString()));
    }
  }
}

