
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UserAccount {
    private String accountName;
    private String fullName;
    private String contactEmail;
    private String passwordHash;
    private List<String> recentLoginTimes;
    
    // Constructors
    public UserAccount(String accountName, String fullName, String contactEmail, String passwordHash, List<String> recentLoginTimes) {
        this.setAccountName(accountName);
        this.setFullName(fullName);
        this.setContactEmail(contactEmail);
        this.setPasswordHash(passwordHash);
        this.setRecentLoginTimes(recentLoginTimes);
    }
    public UserAccount(String jsonString) {
        this(parseJson(jsonString, "accountName"),
        parseJson(jsonString, "fullName"),
        parseJson(jsonString, "contactEmail"),
        parseJson(jsonString, "passwordHash"),
        parseJsonArray(jsonString, "recentLoginTimes"));
    }
    
    // Validation methods
    private void setAccountName(String accountName) {
        if (accountName == null || accountName.isEmpty() || accountName.length() < 3 || accountName.length() > 20) {
            throw new IllegalArgumentException("Account name must be between 3 and 20 characters.");
        }
        this.accountName = accountName;
    }
    
    private void setFullName(String fullName) {
        if (fullName == null || fullName.isEmpty() || fullName.length() > 50) {
            throw new IllegalArgumentException("Full name must not be empty and should be less than 50 characters.");
        }
        this.fullName = fullName;
    }
    
    private void setContactEmail(String contactEmail) {
        if (contactEmail == null || !isValidEmail(contactEmail)) {
            throw new IllegalArgumentException("Invalid email format.");
        }
        this.contactEmail = contactEmail;
    }
    
    private void setPasswordHash(String passwordHash) {
        if (passwordHash == null || passwordHash.isEmpty() || passwordHash.length() != 64) { // Assuming SHA-256 hash
            throw new IllegalArgumentException("Password hash must be a 64-character string.");
        }
        this.passwordHash = passwordHash;
    }
    
    private void setRecentLoginTimes(List<String> recentLoginTimes) {
        if (recentLoginTimes == null) {
            this.recentLoginTimes = new ArrayList<>();
        } else {
            this.recentLoginTimes = new ArrayList<>(recentLoginTimes);
        }
    }
    
    // Utility method to validate email format
    private boolean isValidEmail(String email) {
        String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$";
        Pattern pattern = Pattern.compile(emailRegex);
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }
    
    // Getters
    public String getAccountName() {
        return accountName;
    }
    
    public String getFullName() {
        return fullName;
    }
    
    public String getContactEmail() {
        return contactEmail;
    }
    
    public String getPasswordHash() {
        return passwordHash;
    }
    
    public List<String> getRecentLoginTimes() {
        return new ArrayList<>(recentLoginTimes);
    }
    
    // Method to convert the object to JSON string
    public String toJson() {
        StringBuilder json = new StringBuilder();
        json.append("{");
        json.append("\"accountName\":\"").
        append(escapeJson(accountName)).
        append("\",");
        json.append("\"fullName\":\"").
        append(escapeJson(fullName)).
        append("\",");
        json.append("\"contactEmail\":\"").append(escapeJson(contactEmail)).append("\",");
        json.append("\"passwordHash\":\"").append(escapeJson(passwordHash)).append("\",");
        json.append("\"recentLoginTimes\":").append(listToJson(recentLoginTimes));
        json.append("}");
        return json.toString();
    }
    
    // Helper method to escape JSON special characters
    private String escapeJson(String value) {
        if (value == null) {
            return "";
        }
        return value.replace("\\", "\\\\")
        .replace("\"", "\\\"")
        .replace("\b", "\\b")
        .replace("\f", "\\f")
        .replace("\n", "\\n")
        .replace("\r", "\\r")
        .replace("\t", "\\t");
    }
    
    // Helper method to convert list to JSON array string
    private String listToJson(List<String> list) {
        StringBuilder json = new StringBuilder();
        json.append("[");
        if (list != null && !list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                json.append("\"").append(escapeJson(list.get(i))).append("\"");
                if (i < list.size() - 1) {
                    json.append(",");
                }
            }
        }
        json.append("]");
        return json.toString();
    }
    
    // Helper method to parse JSON string
    private static String parseJson(String jsonString, String key) {
        String regex = String.format("\"%s\":\"(.*?)\"", key);
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(jsonString);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
    
    // Helper method to parse JSON array
    private static List<String> parseJsonArray(String jsonString, String key) {
        String regex = String.format("\"%s\":\\[(.*?)\\]", key);
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(jsonString);
        List<String> list = new ArrayList<>();
        if (matcher.find()) {
            String arrayString = matcher.group(1);
            if (!arrayString.isEmpty()) {
                String[] items = arrayString.split(",");
                for (String item : items) {
                    list.add(item.replace("\"", "").trim());
                }
            }
        }
        return list;
    }
    
    // toString method
    @Override
    public String toString() {
        return "UserAccount{" +
                "accountName='" + accountName + '\'' +
                ", fullName='" + fullName + '\'' +
                ", contactEmail='" + contactEmail + '\'' +
                ", passwordHash='" + passwordHash + '\'' +
                ", recentLoginTimes=" + recentLoginTimes +
                "}";
    }
    
    // testing
    public static void main(String[] args) {
        var account = new UserAccount("john_doe", 
        "John Doe", 
        "john.doe@example.com", 
        "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", 
        null);
        var json = account.toJson();
        System.out.println(json);
        var account2 = new UserAccount(json);
        System.out.println(account2);
    }
}
