use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, TimeZone, Utc};

#[derive(Default)]
pub(super) struct IcalRecord {
    pub summary: String,
    pub note: String,
    pub when_at: Option<String>,
    pub done: bool,
    pub completed_at: Option<String>,
    pub priority: Option<i64>,
    pub categories: Vec<String>,
    pub recurrence: String,
}

pub(super) fn parse_ical_date(value: &str) -> Option<String> {
    if let Ok(date_time) = DateTime::parse_from_rfc3339(value) {
        return Some(date_time.to_rfc3339());
    }
    if let Ok(date_time) = NaiveDateTime::parse_from_str(value, "%Y%m%dT%H%M%SZ") {
        return Some(DateTime::<Utc>::from_naive_utc_and_offset(date_time, Utc).to_rfc3339());
    }
    if let Ok(date_time) = NaiveDateTime::parse_from_str(value, "%Y%m%dT%H%M%S") {
        return Local
            .from_local_datetime(&date_time)
            .single()
            .map(|value| value.to_rfc3339());
    }
    NaiveDate::parse_from_str(value, "%Y%m%d")
        .ok()
        .and_then(|date| date.and_hms_opt(9, 0, 0))
        .and_then(|date_time| Local.from_local_datetime(&date_time).single())
        .map(|date_time| date_time.to_rfc3339())
}

pub(super) fn ical_unescape(value: &str) -> String {
    value
        .replace("\\n", "\n")
        .replace("\\N", "\n")
        .replace("\\,", ",")
        .replace("\\;", ";")
        .replace("\\\\", "\\")
}

pub(super) fn rrule_to_recurrence(value: &str) -> String {
    let upper = value.to_uppercase();
    let frequency = upper
        .split(';')
        .find_map(|part| part.strip_prefix("FREQ="))
        .unwrap_or("");
    let interval = upper
        .split(';')
        .find_map(|part| part.strip_prefix("INTERVAL="))
        .and_then(|value| value.parse::<u32>().ok())
        .unwrap_or(1);
    if upper.contains("BYDAY=MO,TU,WE,TH,FR") {
        return "weekdays".into();
    }
    if interval == 1 {
        return match frequency {
            "DAILY" => "daily",
            "WEEKLY" => "weekly",
            "MONTHLY" => "monthly",
            "YEARLY" => "yearly",
            _ => "",
        }
        .into();
    }
    let unit = match frequency {
        "DAILY" => "days",
        "WEEKLY" => "weeks",
        "MONTHLY" => "months",
        "YEARLY" => "years",
        _ => return String::new(),
    };
    format!("every {interval} {unit}")
}
