use chrono::{DateTime, Utc};
use uuid::Uuid;
use crate::error::{CommonResult as Result, CommonError as Error};

/// Get current timestamp
pub fn now() -> DateTime<Utc> {
    Utc::now()
}

/// Get timestamp from Unix timestamp
pub fn from_timestamp(timestamp: i64) -> Result<DateTime<Utc>> {
    DateTime::from_timestamp(timestamp, 0)
        .ok_or_else(|| Error::ValidationError(format!("Invalid timestamp: {}", timestamp)))
}

/// Calculate time difference in seconds
pub fn time_diff_seconds(start: DateTime<Utc>, end: DateTime<Utc>) -> i64 {
    (end - start).num_seconds()
}

/// Check if timestamp is expired
pub fn is_expired(timestamp: DateTime<Utc>, ttl_seconds: u64) -> bool {
    let now = Utc::now();
    (now - timestamp).num_seconds() > ttl_seconds as i64
}

/// Generate pagination cursor
pub fn generate_cursor(timestamp: DateTime<Utc>, id: Uuid) -> String {
    use crate::utils::crypto::encode_base64;
    let data = format!("{}:{}", timestamp.timestamp(), id);
    encode_base64(data.as_bytes())
}

/// Parse pagination cursor
pub fn parse_cursor(cursor: &str) -> Result<(DateTime<Utc>, Uuid)> {
    use crate::utils::crypto::decode_base64;
    
    let data = decode_base64(cursor)?;
    let data_str = String::from_utf8(data)
        .map_err(|e| Error::ValidationError(format!("Invalid cursor format: {}", e)))?;
    
    let parts: Vec<&str> = data_str.split(':').collect();
    if parts.len() != 2 {
        return Err(Error::ValidationError("Invalid cursor format".to_string()));
    }
    
    let timestamp = parts[0].parse::<i64>()
        .map_err(|_| Error::ValidationError("Invalid timestamp in cursor".to_string()))?;
    
    let id = parts[1].parse::<Uuid>()
        .map_err(|_| Error::ValidationError("Invalid UUID in cursor".to_string()))?;
    
    let datetime = from_timestamp(timestamp)?;
    Ok((datetime, id))
}
