use chrono::Utc;
use ulid::Ulid;
use uuid::Uuid;

pub enum UidType {
    Ulid,
    Uid4,
    Uid7,
}

const MAX_NUMBER_OF_ULIDS: i32 = 100;

pub fn generate_uids(number_of_ulids: i32, uid_type: UidType) -> Vec<String> {
    let mut local_number: i32 = 100;
    if number_of_ulids < MAX_NUMBER_OF_ULIDS {
        local_number = number_of_ulids;
    }

    let mut v = Vec::<String>::new();

    for _ in 0..local_number {
        match uid_type {
            UidType::Ulid => {
                let ulid = Ulid::new();
                v.push(ulid.to_string());
            }
            UidType::Uid4 => {
                // Create UUID V4 uppercase and no hyphens
                let mut uuid_string = Uuid::new_v4().to_string().to_uppercase().replace("-", "");

                // Get current time in nanoseconds since epoch if available
                let nanos = Utc::now().timestamp_nanos_opt().unwrap_or(0);

                // Convert nanoseconds to uppercase hex
                let hex_nanos = format!("{:X}", nanos);
                uuid_string = format!("{}-{}", hex_nanos, uuid_string);

                v.push(uuid_string.to_string());
            }
            UidType::Uid7 => {
                let uuid_str = Uuid::now_v7().to_string();
                v.push(uuid_str);
            }
        }
    }

    v
}

pub fn get_ulid() -> String {
    let ulid = Ulid::new();
    let ulid_string = ulid.to_string();
    ulid_string
}
