/// UUID Version 7 (Time-ordered) implementation

///|
/// Get current Unix timestamp in milliseconds
fn current_timestamp_ms() -> Int64 {
  @env.now().reinterpret_as_int64()
}

///|
/// Generate a time-ordered UUID (version 7)
/// Format: 48-bit timestamp + 12-bit random + 2-bit variant + 62-bit random
pub fn v7() -> Uuid {
  let timestamp = current_timestamp_ms()
  let random_bytes = random_bytes(10) // 10 bytes of random data
  let bytes : FixedArray[Byte] = FixedArray::make(16, b'\x00')

  // First 48 bits (6 bytes) are the timestamp in milliseconds
  bytes[0] = (timestamp >> 40).land(0xFFL).to_int().to_byte()
  bytes[1] = (timestamp >> 32).land(0xFFL).to_int().to_byte()
  bytes[2] = (timestamp >> 24).land(0xFFL).to_int().to_byte()
  bytes[3] = (timestamp >> 16).land(0xFFL).to_int().to_byte()
  bytes[4] = (timestamp >> 8).land(0xFFL).to_int().to_byte()
  bytes[5] = timestamp.land(0xFFL).to_int().to_byte()

  // Next 12 bits are random (use first 1.5 bytes of random data)
  bytes[6] = random_bytes[0]
  bytes[7] = random_bytes[1]

  // Remaining bytes are random
  for i = 8; i < 16; i = i + 1 {
    bytes[i] = random_bytes[i - 6] // Offset by 6 since we used first 2 random bytes
  }

  // Set version and variant bits
  set_variant_and_version(bytes, Version::V7)
  Uuid::new(bytes)
}

///|
/// Generate a time-ordered UUID with specific timestamp
pub fn v7_with_timestamp(timestamp_ms : Int64) -> Uuid {
  let random_bytes = random_bytes(10)
  let bytes : FixedArray[Byte] = FixedArray::make(16, b'\x00')

  // First 48 bits (6 bytes) are the timestamp in milliseconds
  bytes[0] = (timestamp_ms >> 40).land(0xFFL).to_int().to_byte()
  bytes[1] = (timestamp_ms >> 32).land(0xFFL).to_int().to_byte()
  bytes[2] = (timestamp_ms >> 24).land(0xFFL).to_int().to_byte()
  bytes[3] = (timestamp_ms >> 16).land(0xFFL).to_int().to_byte()
  bytes[4] = (timestamp_ms >> 8).land(0xFFL).to_int().to_byte()
  bytes[5] = timestamp_ms.land(0xFFL).to_int().to_byte()

  // Fill remaining bytes with random data
  for i = 6; i < 16; i = i + 1 {
    bytes[i] = random_bytes[i - 6]
  }

  // Set version and variant bits
  set_variant_and_version(bytes, Version::V7)
  Uuid::new(bytes)
}

///|
/// Extract timestamp from a version 7 UUID
pub fn extract_timestamp(uuid : Uuid) -> Int64? {
  match uuid.version() {
    Some(Version::V7) => {
      let bytes = uuid.bytes()
      let timestamp = (bytes[0].to_int64() << 40) +
        (bytes[1].to_int64() << 32) +
        (bytes[2].to_int64() << 24) +
        (bytes[3].to_int64() << 16) +
        (bytes[4].to_int64() << 8) +
        bytes[5].to_int64()
      Some(timestamp)
    }
    _ => None
  }
}

///|
/// Generate multiple time-ordered UUIDs ensuring monotonicity
pub fn v7_sequence(count : Int) -> Array[Uuid] {
  let base_timestamp = current_timestamp_ms()
  let result : Array[Uuid] = []
  for i = 0; i < count; i = i + 1 {
    // Increment timestamp slightly to ensure ordering
    let timestamp = base_timestamp + i.to_int64()
    result.push(v7_with_timestamp(timestamp))
  }
  result
}