@startuml UserManagementService

interface IUser {
    +   socialMediaLogin()      :   json

    +   get_profile()       :   json
    +   update_profile()    :   bool
    +   hashPassword(password: str)   :   str
    +   get_my_reviews()    :   List<RatingAndReview>
}

class StudioManagementService {
    +     StudioID: String

    +     approve_aadhar_details()    :   tuple(approved   :   bool, Message   :   str)
    -     approve_studio_photos()     :   tuple(approved   :   bool, Message   :   str)
    -     approve_owner_photo()       :   tuple(approved   :   bool, Message   :   str)
}
class PasswordReset {
    <<constructor>> PasswordReset(userID: str)    : void

    +   reset_password(otp, new_password)        :   bool
    -   isEmail()               :   bool
    -   generateOTP()           :   int
    -   sendOTP(otp: int)               :   void
    -   validateOTP()           :   bool
    -   is_otp_expired()        :   bool

    +   change_password(old_password, new_password)     : bool
    -   validatePassword()      :   bool
    -   isSocialMediaLogin()    :   bool
}

class CustomerProfileValidations {
    <<constructor>> CustomerProfileValidations(userProfile : CustomerProfile)    : void
    -   userProfile : json

    +   validateReCaptcha()     :   bool


    #   validateName()          :   bool
    #   validatePhoneNumber(PhoneNumber: int)   :   bool
    #   validateEmail()         :   bool
    #   validatePassword()      :   bool
    #   validateReferralCode()  :   bool

}
class StudioProfileValidations extends CustomerProfileValidations {
    <<constructor>> StudioProfileValidations(userProfile : StudioProfile)    : void
    -   userProfile : json

    -   validate_GSTIN()       :   bool
    -   validate_aadhar_number()      :   bool  '   Regex
    -   authenticate_aadhar()      :   bool

}
class Customer implements IUser{
    <<constructor>> Customer(config : json)    : void

    -   config              : json
    -   id                  : int

    -   mysql                   :   MySQL(db_name: str)
    -   redis                   :   Redis(db_name: str)
    -   referralService         :   ReferralService(config : json)
    -   validations_obj         :   CustomerProfileValidations(details: CustomerProfile)
    -   wallet                  :   WalletService()

    +   view_saved_cards()                              :   List<Credit_debit_card>
    +   add_card(card_details   :   Credit_debit_card)  :   bool
    +   delete_card(nickName    :   str)                :   bool

    +   login(userName, password)   :   tuple(success: bool, sessionID: str, name: str, location: tuple<str, str>)
    -   addLoginTimeToDB()  :   void
    -   isEmail()                   :   bool
    -   startSession()              :   str
    +   logout()                    :   void
    -   addLogoutTimeToDB(datetime)  :   void

    +   socialMediaLogin()      :   json
    +   create_user(details: CustomerProfile)           :   void
    +   update_profile(details: CustomerProfile)    :   bool
    -   hashPassword(password: str)   :   str

    +   get_profile()       :   CustomerProfile
    -   view_saved_addresses()  : List<str>

    +   viewTransactions()  :   json<PaymentTransaction>
    +   get_my_reviews()    :   List<RatingAndReview>
}
class Studio implements IUser{
    <<constructor>> Studio(config : json)  : void

    -   config              :   json
    -   id                  :   int

    -   mysql                           :   MySQL(db_name: str)
    -   redis                           :   Redis(db_name: str)
    -   referralService                 :   ReferralService(config : json)
    -   validations_obj                 :   StudioProfileValidations(details: StudioProfile)
    -   wallet                          :   WalletService()
    -   kyc                             :   KYCService(id: int)

    +   socialMediaLogin()      :   json
    +   create_user(details: CustomerProfile)           :   void
    -   hashPassword(password: str)   :   str

    +   upload(picture_type: enum(aadhar, studio_photos, owner_photo), images_local_locations  :   List<str>)      :   str ' S3 link. 1 - 3 pics can be selected

    +   get_profile()                   :   StudioProfile
    +   update_profile(details: StudioProfile)   :   bool

    +   login(userName, password)   :   tuple(success: bool, sessionID: str, name: str, location: tuple<str, str>)
    -   isEmail()               :   bool
    -   startSession()      :   str
    +   logout()            :   void

    +   get_my_reviews()    :   List<RatingAndReview>
}
class Credit_debit_card {
    -   number: int
    +   last_four_digits: int
    +   expiryDate: str
    -   cvv: str
    +   nickName: str
    +   network:   enum (Visa, Master)
    +   bank    :   str
}
class CustomerProfile {
    +   id                  : int
    +   name                : str
    +   last_location       : str
    +   phoneNumber         : str
    +   email               : str
    -   password            : str
    +   myReferralCode      : str
    +   role                : str(constant) ' Customer
}
class StudioProfile {
    +   id                  : int
    +   name                : str
    +   phoneNumber         : str
    +   email               : str
    -   password            : str
    +   myReferralCode      : str
    +   location            : tuple<str, str>
    +   gstin               : str
    +   address             : str
    +   studioPhotosUrl     : tuple<str, str, str>
    +   ownerName           : str
    +   ownerPhotoUrl       : str
    +   ownerPhoneNumber    : str
    +   owner_aadhar_number : int
    +   aadharUrl           : str
    +   homePageURL         : str
    +   averageRating       : float
    +   role                : str(constant) ' Studio
}
class ModeratorProfile extends CustomerProfile{
    +   role                : str(constant) ' Moderator
}
class Moderator extends Customer{
    <<constructor>> Moderator(config : json)  : void
    -   config              : json
    -   id                  : int

    +   get_all_customers()    :   List<CustomerProfile>
    +   get_all_studios()      :   List<StudioProfile>

    +   block_user(id: int)    :   void
    +   unblock_user(id: int)  :   void

    -   search_obj              : SearchService()

    +   set_marketing_role(id: int)  :   void
    -   studioManagement_obj     :   StudioManagementService(studioID: int)


}
class SearchService{
    <<constructor>> SearchService()  : void

    +   search_string   :   str

    -   elasticSearch_obj    :   ElasticSearch()
}
class ElasticSearch{
    <<constructor>> ElasticSearch()  : void

    +   fetch_customer_data()  :   List<CustomerProfile
    +   fetch_studio_data()  :   List<StudioProfile>
}


' Studio --> MySQL                        : Uses    Removing to reduce complexity in diagram
' Customer --> MySQL                        : Uses
Customer --> Redis                        : Uses
Studio --> Redis                        : Uses

Customer   "1" -- "*" PaymentTransaction   : has-many
Studio   "1" -- "*" PaymentTransaction   : has-many

Customer   "1" -- "*" PaymentTransaction   : has-many
Studio   "1" -- "*" PaymentTransaction   : has-many

Customer   "1" -- "*" RatingAndReview   : has-many
Studio   "1" -- "*" RatingAndReview   : has-many

Customer *-- CustomerProfile                          : has-a
Studio *-- StudioProfile                          : has-a
Moderator *-- ModeratorProfile                          : has-a

Moderator *-- StudioManagementService                          : has-a
Moderator *-- SearchService                          : has-a
SearchService *-- ElasticSearch                          : has-a

Customer *-- CustomerProfileValidations                          : has-a
Studio *-- StudioProfileValidations                          : has-a

Customer   "1" -- "*" Credit_debit_card   : has-many
Studio   "1" -- "*" Credit_debit_card   : has-many

@enduml

