package com.airlock.iam.common.domain.service.phone;

import com.airlock.iam.base.api.domain.model.exception.ViolationException;
import com.airlock.iam.common.api.domain.model.phonenumber.PhoneNumber;
import com.airlock.iam.common.domain.model.phone.VisiblePhoneNumberDigits;
import com.airlock.iam.core.domain.model.phone.CountryCallingCode;
import com.airlock.iam.core.misc.util.phone.PhoneUtils;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.text.ParseException;
import lombok.NonNull;

public class PhoneNumberService {
   private static final ELogger LOG = ELoggerFactory.getLogger(PhoneNumberService.class);
   private final VisiblePhoneNumberDigits visiblePhoneNumberDigits;
   private final CountryCallingCode countryCallingCode;

   @Inject
   PhoneNumberService(@NonNull VisiblePhoneNumberDigits visiblePhoneNumberDigits, @NonNull CountryCallingCode countryCallingCode) {
      if (visiblePhoneNumberDigits == null) {
         throw new NullPointerException("visiblePhoneNumberDigits is marked non-null but is null");
      }

      if (countryCallingCode == null) {
         throw new NullPointerException("countryCallingCode is marked non-null but is null");
      }

      this.visiblePhoneNumberDigits = visiblePhoneNumberDigits;
      this.countryCallingCode = countryCallingCode;
   }

   public String maskPhoneNumber(String phoneNumber) {
      return PhoneUtils.maskPhoneNumber(phoneNumber, this.visiblePhoneNumberDigits.getCount());
   }

   public String normalizePhoneNumber(String phoneNumber) {
      try {
         return PhoneUtils.normalizePhoneNumber(phoneNumber, this.countryCallingCode.getCode());
      } catch (ParseException e) {
         LOG.debug("Service failure parsing the phone number");
         throw new ViolationException("Error while parsing mobile phone number", e);
      }
   }

   public PhoneNumber normalizePhoneNumber(PhoneNumber phoneNumber) {
      return PhoneNumber.phoneNumber(this.normalizePhoneNumber(phoneNumber.getValue()));
   }

   public boolean isValidPhoneNumber(String phoneNumber) {
      try {
         this.normalizePhoneNumber(phoneNumber);
         return true;
      } catch (ViolationException e) {
         return false;
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public static PhoneNumberService.PhoneNumberServiceBuilder builder() {
      return new PhoneNumberService.PhoneNumberServiceBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class PhoneNumberServiceBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private VisiblePhoneNumberDigits visiblePhoneNumberDigits;
      @SuppressFBWarnings(justification = "generated code")
      private CountryCallingCode countryCallingCode;

      @SuppressFBWarnings(justification = "generated code")
      PhoneNumberServiceBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public PhoneNumberService.PhoneNumberServiceBuilder visiblePhoneNumberDigits(@NonNull VisiblePhoneNumberDigits visiblePhoneNumberDigits) {
         if (visiblePhoneNumberDigits == null) {
            throw new NullPointerException("visiblePhoneNumberDigits is marked non-null but is null");
         }

         this.visiblePhoneNumberDigits = visiblePhoneNumberDigits;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public PhoneNumberService.PhoneNumberServiceBuilder countryCallingCode(@NonNull CountryCallingCode countryCallingCode) {
         if (countryCallingCode == null) {
            throw new NullPointerException("countryCallingCode is marked non-null but is null");
         }

         this.countryCallingCode = countryCallingCode;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public PhoneNumberService build() {
         return new PhoneNumberService(this.visiblePhoneNumberDigits, this.countryCallingCode);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "PhoneNumberService.PhoneNumberServiceBuilder(visiblePhoneNumberDigits="
            + this.visiblePhoneNumberDigits
            + ", countryCallingCode="
            + this.countryCallingCode
            + ")";
      }
   }
}
