#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate horrorshow;
#[macro_use]
extern crate lazy_static;

use chrono::{Datelike, Local, TimeZone, Utc};
use fluent::{FluentArgs, FluentValue};
use geo_types::{Latitude, Longitude};
use horrorshow::helper::doctype;
use horrorshow::prelude::*;
use ifc;
use std::{
    borrow::Cow,
    net::{IpAddr, Ipv4Addr, SocketAddr},
    sync::Arc,
};
use warp::{reply::Html, Filter, Rejection};

mod soluna_client;
use soluna_client::{SolunaClient, SunMoon};

mod solstices;
use solstices::{Event, EVENTS};

/*
const EO_TEXT: &'static str = "
day = {$day ->
    *[Sunday] Dimanĉo
    [Monday] Lundo
    [Tuesday] Mardo
    [Wednesday] Merkredo
    [Thursday] Ĵaŭdo
    [Friday] Vendredo
    [Saturday] Sabato
    [LeapDay] Leap Day
    [YearDay] Year Day
}
month = {$month ->
    *[January] Januaro
    [February] Februaro
    [March] Marto
    [April] Aprilo
    [May] Mayo
    [June] Junio
    [Sol] Solo
    [July] Julio
    [August] Aŭgusto
    [September] Septembro
    [October] Oktobro
    [November] Novembro
    [December] Decembro
}
spring_equinox = Printempa Ekvinokso
summer_solstice = Somera Solstico
autumn_equinox = Aŭtuna Ekvinokso
winter_solstice = Vintra Solstico
";

fn date(fluent: Arc<fluent_ergonomics::FluentErgo>, today: ifc::IFC) -> impl Render {
    let mut day_args = FluentArgs::new();
    day_args.set(
        "day",
        FluentValue::String(Cow::Owned(String::from(today.weekday_ifc()))),
    );
    let tago = fluent.tr("tago", Some(&day_args)).unwrap();

    let mut month_args = FluentArgs::new();
    month_args.set(
        "month",
        FluentValue::String(Cow::Owned(String::from(today.month_ifc()))),
    );
    let monato = fluent.tr("month", Some(&month_args)).unwrap();

    owned_html! {p : format!("{}, {} {}, {}", tago, monato, today.day(), today.year());}
}
*/

/*
fn soluna_desegno<Tz: TimeZone>(sun_moon: SunMoon<Tz>) -> impl Render {
    owned_html! {
        table {
            tr {
                th : "Sunleviĝo";
                th : "Sunfalo";
                th : "Lunleviĝo";
                th : "Lunfalo";
            }
            tr {
                td : format!("{}", sun_moon.sunrise.format("%H:%M"));
                td : format!("{}", sun_moon.sunset.format("%H:%M"));
                td : sun_moon.moonrise.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
                td : sun_moon.moonset.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
                td : format!("{:?}", sun_moon.moon_phase);
            }
        }
    }
}
*/

/*
fn astronomia_eventa_desegno(
    fluent: Arc<fluent_ergonomics::FluentErgo>,
    event: Option<Event>,
) -> impl Render {
    let s = match event {
        None => "".to_owned(),
        Some(event) => {
            let eventa_str = match event {
                Event::SpringEquinox(_) => fluent.tr("spring_equinox", None),
                Event::SummerSolstice(_) => fluent.tr("summer_solstice", None),
                Event::AutumnEquinox(_) => fluent.tr("autumn_equinox", None),
                Event::WinterSolstice(_) => fluent.tr("winter_solstice", None),
            }
            .unwrap();
            format!("{} {}", eventa_str, event.date().format("%Y-%m-%d"))
        }
    };
    owned_html! {
        div : s.clone();
    }
}
*/

/*
fn page_template(
    fluent: Arc<fluent_ergonomics::FluentErgo>,
    today: ifc::IFC,
    sun_moon: SunMoon,
    event: Option<solstices::Event>,
) -> String {
    format!(
        "{}",
        html! {
            : doctype::HTML;
            html {
                head {
                    title: "Superrigardo";
                }
                body {
                    h1(id="heading", class="title") : date(fluent.clone(), today);
                    div : soluna_desegno(sun_moon.clone());
                    div : astronomia_eventa_desegno(fluent.clone(), event);
                    // div : cirklo();
                }
            }
        }
    )
}

async fn page(
    fluent: Arc<fluent_ergonomics::FluentErgo>,
    solar_client: Arc<SolunaClient>,
    latitude: Latitude,
    longitude: Longitude,
) -> Result<Html<String>, Rejection> {
    let now = Utc::now();
    let d = ifc::IFC::from(now.with_timezone(&New_York).date());
    let sun_moon = solar_client
        .request(latitude, longitude, now.with_timezone(&New_York).date())
        .await;
    let next_event = EVENTS.next_event(now);
    Ok(warp::reply::html(page_template(
        fluent, d, sun_moon, next_event,
    )))
}
*/

#[tokio::main]
pub async fn main() {
    let now = Local::now();
    let ifc = ifc::IFC::from(now.date_naive().with_year(12023).unwrap());
    let next_event = EVENTS.next_event(now.with_timezone(&Utc)).unwrap();

    println!(
        "{:?}, {:?} {}, {}",
        ifc.weekday(),
        ifc.month(),
        ifc.day(),
        ifc.year()
    );

    println!("{:?}", next_event);

    let latitude = Latitude::from(41.78);
    let longitude = Longitude::from(-71.41);
    let soluna_client = SolunaClient::new();
    let sun_moon = soluna_client
        .request(latitude, longitude, Local::now())
        .await;

    println!(
        "Solar Transit: {} -> {}",
        sun_moon.sunrise.format("%H:%M").to_string(),
        sun_moon.sunset.format("%H:%M").to_string()
    );
    println!(
        "Lunar Transit: {} -> {} [{:?}]",
        sun_moon
            .moonrise
            .map(|time| time.format("%H:%M").to_string())
            .unwrap_or(" -- ".to_owned()),
        sun_moon
            .moonset
            .map(|time| time.format("%H:%M").to_string())
            .unwrap_or(" -- ".to_owned()),
        sun_moon.moon_phase
    );
}
