use crate::config::Config;
use crate::core::calculator::{expected, surplus, timeline};
use crate::models::{day_summary::DaySummary, event::Event};
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
pub struct Core;
impl Core {
pub fn build_daily_summary(events: &[Event], cfg: &Config) -> DaySummary {
let timeline = timeline::build_timeline(events);
let expected = expected::calculate_expected(&timeline, cfg);
let surplus = surplus::calculate_surplus(&timeline, expected);
DaySummary {
timeline,
expected,
surplus,
gaps: Default::default(), }
}
pub fn calculate_expected_exit(
date: NaiveDate, time_in: &str, work_minutes: i32, lunch_total: i32, ) -> NaiveDateTime {
let (hours, minutes) = time_in
.split_once(':')
.map(|(h, m)| {
let h = h.parse::<i32>().unwrap_or(0);
let m = m.parse::<i32>().unwrap_or(0);
(h, m)
})
.expect("Invalid time_in format");
let start_total_min = hours * 60 + minutes;
let exit_total_min = start_total_min + work_minutes + lunch_total;
let exit_hours = (exit_total_min / 60) % 24;
let exit_minutes = exit_total_min % 60;
let exit_time =
NaiveTime::parse_from_str(&format!("{:02}:{:02}", exit_hours, exit_minutes), "%H:%M")
.expect("Invalid generated time");
let days_to_add = exit_total_min / (24 * 60);
let final_date = date + chrono::Duration::days(days_to_add as i64);
NaiveDateTime::new(final_date, exit_time)
}
pub fn parse_work_duration_to_minutes(s: &str) -> i64 {
let s = s.trim();
if s.is_empty() {
return 8 * 60;
}
if let Some(h_pos) = s.find('h') {
let (h_part, rest) = s.split_at(h_pos);
let hours: i64 = h_part.trim().parse().unwrap_or(8);
let mut minutes: i64 = 0;
let rest = rest[1..].trim();
if !rest.is_empty() {
let rest_no_m = if let Some(m_pos) = rest.find('m') {
let (m_part, _) = rest.split_at(m_pos);
m_part.trim()
} else {
rest
};
if !rest_no_m.is_empty() {
minutes = rest_no_m.parse::<i64>().unwrap_or(0);
}
}
return hours * 60 + minutes;
}
if let Some(colon_pos) = s.find(':') {
let (h_part, m_part) = s.split_at(colon_pos);
let hours: i64 = h_part.trim().parse().unwrap_or(8);
let minutes: i64 = m_part[1..].trim().parse().unwrap_or(0);
return hours * 60 + minutes;
}
if let Ok(h) = s.parse::<i64>() {
let total = h * 60;
return total;
}
8 * 60
}
}