use chrono::{Months, NaiveDate, NaiveDateTime, Utc};
use serde::Deserialize;
use serde_repr::Deserialize_repr;

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CalendarAPIDatum {
    pickup_dates: Vec<NaiveDateTime>,
    pickup_type: TrashType,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct CalendarAPIResponse {
    data_list: Vec<CalendarAPIDatum>,
}

#[derive(Copy, Clone, Deserialize_repr, Debug)]
#[repr(u8)]
pub(crate) enum TrashType {
    Grey = 0,
    Green = 1,
    Paper = 2,
    Packages = 10,
}

pub(crate) async fn get_pickup_dates() -> Result<Vec<(TrashType, NaiveDate)>, reqwest::Error> {
    let today = Utc::now().date_naive();
    let next_month = (today + Months::new(1)).to_string();
    let today = today.to_string();

    let client = reqwest::Client::new();

    let params = [
        ("companyCode", "8d97bb56-5afd-4cbc-a651-b4f7314264b4"),
        ("uniqueAddressID", "1300002485"),
        ("startDate", &today),
        ("endDate", &next_month),
    ];

    let calendar = client
        .post("https://twentemilieuapi.ximmio.com/api/GetCalendar")
        .form(&params)
        .send()
        .await?
        .json::<CalendarAPIResponse>()
        .await?;

    Ok(calendar
        .data_list
        .iter()
        .flat_map(|datum| {
            datum
                .pickup_dates
                .iter()
                .map(|date| (datum.pickup_type, NaiveDate::from(*date)))
        })
        .collect::<Vec<(TrashType, NaiveDate)>>())
}