// Mostly nicked from https://github.com/icykoneko/ff14-fish-tracker-app/blob/master/js/app/time.js. Thanks!

use chrono::{DateTime, Duration, Timelike, Utc};

const EARTH_TO_EORZEA: f64 = 3600. / 175.;
const EORZEA_TO_EARTH: f64 = 1. / EARTH_TO_EORZEA;

/// Converts a human timestamp to an Eorzean one.
pub fn to_eorzea_time(earth_time: DateTime<Utc>) -> DateTime<Utc> {
    let et_ts = earth_time.timestamp();
    let new_ts = et_ts.abs() as f64 * EARTH_TO_EORZEA;
    DateTime::from_timestamp(new_ts.floor() as i64, 0).unwrap()
}

/// Gets the current date and time in Eorzea. Arguably you will never need the date, though,
/// because it isn't shown anywhere in the game, the time is what matters.
pub fn get_current_eorzea_date() -> DateTime<Utc> {
    to_eorzea_time(Utc::now())
}

/// Converts an Eorzean timestamp to human time.
pub fn to_earth_time(ez_time: DateTime<Utc>) -> DateTime<Utc> {
    let ez_ts = ez_time.timestamp();
    let new_ts = (ez_ts.abs() as f64 * EORZEA_TO_EARTH).ceil();
    DateTime::from_timestamp(new_ts as i64, 0).unwrap()
}

/// Sets hours and minutes for a date, based on a f32.
pub fn set_hm_from_float(date: &DateTime<Utc>, hm: f32) -> DateTime<Utc> {
    let minutes_only = hm - (hm as u32 as f32); // Remove decimal points so we can subtract the whole number
    let minutes = (minutes_only * 60.) as u32;
    let hm = if hm as u32 == 24 { 0. } else { hm };
    date.date_naive()
        .and_hms_opt(hm as u32, minutes, date.second())
        .unwrap()
        .and_utc()
}

/// Calculates the length between a window start time and end time, and returns it as a Duration.
pub fn get_window_duration(start_time: f32, end_time: f32) -> Duration {
    let diff_float = if end_time > start_time {
        end_time - start_time
    } else {
        (24. - start_time) + end_time
    };
    let minutes = (diff_float - (diff_float as u32 as f32) * 60.) as u32;
    Duration::minutes(((diff_float as u32) * 60 + minutes) as i64)
}

pub fn display_eorzea_time(date: &DateTime<Utc>) -> String {
    date.format("%H:%M").to_string()
}
