use crate::{
    drawing::{Color, PieChart, Wedge},
    soluna_client::SunMoon,
};
use chrono::{Duration, NaiveTime};
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
use std::{cell::RefCell, f64::consts::PI, rc::Rc};

#[derive(Default)]
pub struct TransitClockPrivate {
    info: Rc<RefCell<Option<SunMoon>>>,
}

#[glib::object_subclass]
impl ObjectSubclass for TransitClockPrivate {
    const NAME: &'static str = "TransitClock";
    type Type = TransitClock;
    type ParentType = gtk::DrawingArea;
}

impl ObjectImpl for TransitClockPrivate {}
impl WidgetImpl for TransitClockPrivate {}
impl DrawingAreaImpl for TransitClockPrivate {}

glib::wrapper! {
    pub struct TransitClock(ObjectSubclass<TransitClockPrivate>) @extends gtk::DrawingArea, gtk::Widget;
}

impl Default for TransitClock {
    fn default() -> Self {
        let s: Self = Object::builder().build();
        s.set_width_request(500);
        s.set_height_request(500);

        s.set_draw_func({
            let s = s.clone();
            move |_, context, width, height| {
                let style_context = WidgetExt::style_context(&s);
                let center_x = width as f64 / 2.;
                let center_y = height as f64 / 2.;
                let radius = width.min(height) as f64 / 2. * 0.9;
                if let Some(ref info) = *s.imp().info.borrow() {
                    let full_day = Duration::days(1).num_seconds() as f64;
                    let sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
                    let sunset = info.sunset - NaiveTime::from_hms_opt(0, 0, 0).unwrap();

                    let night_color = style_context.lookup_color("dark_5").unwrap();
                    let day_color = style_context.lookup_color("blue_1").unwrap();

                    PieChart::new(&style_context)
                        .center(center_x, center_y)
                        .radius(radius)
                        .rotation(-PI / 2.)
                        .wedges(
                            vec![
                                Wedge {
                                    start_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day,
                                    end_angle: (PI * 2.) * sunrise.num_seconds() as f64 / full_day,
                                    color: Color {
                                        r: night_color.red() as f64,
                                        g: night_color.green() as f64,
                                        b: night_color.blue() as f64,
                                    },
                                },
                                Wedge {
                                    start_angle: (PI * 2.) * sunrise.num_seconds() as f64
                                        / full_day,
                                    end_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day,
                                    color: Color {
                                        r: day_color.red() as f64,
                                        g: day_color.green() as f64,
                                        b: day_color.blue() as f64,
                                    },
                                },
                            ]
                            .into_iter(),
                        )
                        .draw(context);

                    (0..24).for_each(|tick| {
                        context.set_source_rgb(0., 0., 0.);
                        context.translate(center_x, center_y);
                        context.rotate(tick as f64 * (PI / 12.));
                        context.move_to(radius - 5., 0.);
                        context.line_to(radius - 10., 0.);
                        let _ = context.stroke();
                        context.identity_matrix();
                    });
                }
            }
        });

        s
    }
}

impl TransitClock {
    pub fn update_transit(&self, transit_info: SunMoon) {
        *self.imp().info.borrow_mut() = Some(transit_info);
        self.queue_draw();
    }
}
