use chrono::{DateTime, Utc};

/// Parse a timestamp from various formats found in Claude Code data.
///
/// Supports:
/// - ISO 8601 string: "2026-03-22T17:00:13.192Z"
/// - Unix milliseconds (number > 1e12): 1769461914249
/// - Unix seconds (number <= 1e12): 1769461914
pub fn parse_timestamp(value: &serde_json::Value) -> Option<DateTime<Utc>> {
    match value {
        serde_json::Value::String(s) => {
            DateTime::parse_from_rfc3339(s)
                .ok()
                .map(|dt| dt.with_timezone(&Utc))
        }
        serde_json::Value::Number(n) => {
            if let Some(ms) = n.as_i64() {
                if ms > 1_000_000_000_000 {
                    DateTime::from_timestamp_millis(ms)
                } else {
                    DateTime::from_timestamp(ms, 0)
                }
            } else {
                None
            }
        }
        _ => None,
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::Datelike;

    #[test]
    fn parse_timestamp_iso8601() {
        let v = serde_json::json!("2026-03-22T17:00:13.192Z");
        let dt = parse_timestamp(&v).unwrap();
        assert_eq!(dt.year(), 2026);
        assert_eq!(dt.month(), 3);
        assert_eq!(dt.day(), 22);
    }

    #[test]
    fn parse_timestamp_unix_millis() {
        let v = serde_json::json!(1769461914249_i64);
        let dt = parse_timestamp(&v).unwrap();
        assert!(dt.year() >= 2025);
    }

    #[test]
    fn parse_timestamp_unix_seconds() {
        let v = serde_json::json!(1769461914_i64);
        let dt = parse_timestamp(&v).unwrap();
        assert!(dt.year() >= 2025);
    }

    #[test]
    fn parse_timestamp_null_returns_none() {
        let v = serde_json::json!(null);
        assert!(parse_timestamp(&v).is_none());
    }

    #[test]
    fn parse_timestamp_invalid_string_returns_none() {
        let v = serde_json::json!("not a date");
        assert!(parse_timestamp(&v).is_none());
    }
}
