use std::time::{Duration, SystemTime};

#[derive(Clone, Copy, serde::Serialize, serde::Deserialize, Debug, derive_more::From)]
#[serde(transparent)]
pub struct TimestampSec(pub u32);

#[derive(Clone, Copy, serde::Serialize, serde::Deserialize, Debug, derive_more::From)]
#[serde(transparent)]
pub struct TimestampMs(pub u64);

impl TimestampSec {
    pub fn now() -> Self {
        Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
    }
    pub fn sec(&self) -> u32 {
        self.0
    }
    pub fn ms(&self) -> u64 {
        self.sec() as u64 * 1000
    }
}
impl TimestampMs {
    pub fn now() -> Self {
        Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
    }
    pub fn sec(&self) -> u32 {
        (self.ms() / 1000) as u32
    }
    pub fn ms(&self) -> u64 {
        self.0
    }
}

impl From<SystemTime> for TimestampMs {
    fn from(value: SystemTime) -> Self {
        Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64)
    }
}
impl From<SystemTime> for TimestampSec {
    fn from(value: SystemTime) -> Self {
        Self(value.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as u32)
    }
}

impl From<TimestampMs> for SystemTime {
    fn from(value: TimestampMs) -> Self {
        SystemTime::UNIX_EPOCH + Duration::from_millis(value.0)
    }
}
impl From<TimestampSec> for SystemTime {
    fn from(value: TimestampSec) -> Self {
        SystemTime::UNIX_EPOCH + Duration::from_secs(value.0 as u64)
    }
}
