@startuml
'https://plantuml.com/class-diagram

interface AccountController {
    ResponseEntity<GeneralResponse<LoginResponse>> login(LoginRequest request);
}

class GeneralResponse {
    _ResponseStatus status;
    LoginResponse data;
}

class _ResponseStatus {
    Integer status;
    String code;
    String message;
    String displayMessage;
}

class LoginRequest {
     String emailOrUsername;
     String password;
}


class LoginResponse {
    String accountId;
    String username;
    String email;
    String fullName;
    String token;
    String refreshToken;
    LocalDateTime tokenExpireTime;
    LocalDateTime refreshTokenExpireTime;
}


class AccountControllerImpl {
    ResponseFactory responseFactory;
    AccountService accountService;
}

class ResponseFactory {
    DisplayMessageService displayMessageService;
}


interface DisplayMessageService {
    String getDisplayMessage(String code);
    String getDisplayMessage(String code, String language);
}

class DisplayMessageServiceImpl {
    DisplayMessageRepository displayMessageRepository;
}

interface DisplayMessageRepository {
}

class DisplayMessageRepository {
    Optional<DisplayMessage> findByCodeAndLanguage(String code, String language);
}

class DisplayMessage {
     String displayMessageId;
     String code;
     String language = "en";
     String message;
}

class Auditor {
    Account createdBy;
    LocalDateTime createdDate;
    Account lastModifiedBy;
    LocalDateTime lastModifiedDate;
    Account deletedBy;
    LocalDateTime deletedDate;
}

interface AccountService {
    LoginResponse login(LoginRequest request);
}


class Account {
         String accountId;
         String email;
         String username;
         String fullName;
         String password;
         List<_Role> roles;
         Profile profile;
         Coin coin;
         List<Advisor> following = new ArrayList<>();
         Boolean isOnline;
}



class AccountServiceImpl {
    AccountRepository accountRepository;
    _TokenService tokenService;
    LoginResponse login(LoginRequest request);
}


class DisplayMessageRepositoryImpl {
    RedisTemplate<String, String> redisTemplate;
    ObjectMapper objectMapper;
    Optional<DisplayMessage> findByCodeAndLanguage(String code, String language)
}

interface AccountRepository {
    Optional<Account> findAccountByEmailOrUsername(String emailOrUsername);
}

class _TokenService {
    String generateToken(Account account, UserDetails userDetails);
}

AccountController o-- GeneralResponse
AccountController <|.. AccountControllerImpl
AccountController o-- LoginRequest
GeneralResponse o-- _ResponseStatus
LoginResponse --* GeneralResponse
AccountControllerImpl o-- AccountService

AccountControllerImpl o-- ResponseFactory
ResponseFactory o-- DisplayMessageService
DisplayMessageService o-- DisplayMessageServiceImpl
DisplayMessageServiceImpl o-- DisplayMessageRepository
DisplayMessageRepository <|.. DisplayMessageRepositoryImpl
DisplayMessageRepositoryImpl o-- DisplayMessage

AccountService <|.. AccountServiceImpl
AccountServiceImpl o-- AccountRepository
Account --* AccountRepository
JpaRepository <|-- AccountRepository

AccountServiceImpl o-- _TokenService

Auditor <|-- Account




@enduml
