use eframe::egui;
use eframe::egui::mutex::RwLock;
use eframe::egui::vec2;
use eframe::egui::Align2;
use eframe::egui::Button;
use eframe::egui::Color32;
use eframe::egui::Label;
use eframe::egui::Link;
use eframe::egui::RichText;
use eframe::egui::ScrollArea;
use eframe::egui::Stroke;
use eframe::egui::TextEdit;
// use eframe::Frame;
use egui_flex::item;
use egui_flex::Flex;
use serde::Deserialize;
use serde::Serialize;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::iter::zip;
use std::sync::Arc;
use std::sync::OnceLock;

use crate::tabs::activities::activity_form::filtered_classrooms;
use crate::tabs::activities::Activity;

use super::activities::activities;
use super::activities::activity_form::classrooms_ui::set_classrooms_filter;
// use super::activities::activity_form::filtered_classes;
// use super::activities::activity_form::filtering_classes;
use super::activities::activity_form::filtering_classrooms;
use super::activities::save_activities;
// use super::limitations::limitations_ui::create_classes_sched;
// use super::classrooms::get_classrooms;
// use super::limitations::limitations_ui::ClassLimitation;
// use super::limitations::limitations_ui::{classes_limitations, save_classes_limitations};

#[derive(Clone, Serialize, Deserialize)]
pub struct ClassRoom {
    pub id: i32,
    pub name: String,
    short_name: String,
}

pub fn selected_classroom() -> &'static Arc<RwLock<Option<i32>>> {
    static SELECTED: OnceLock<Arc<RwLock<Option<i32>>>> = OnceLock::new();
    SELECTED.get_or_init(|| Arc::new(RwLock::new(None)))
}
pub fn get_classrooms() -> &'static Arc<RwLock<BTreeMap<i32, ClassRoom>>> {
    static CLASSES: OnceLock<Arc<RwLock<BTreeMap<i32, ClassRoom>>>> = OnceLock::new();
    CLASSES.get_or_init(|| Arc::new(RwLock::new(read_classrooms())))
}
pub fn del_classrooms_state() -> &'static Arc<RwLock<Vec<bool>>> {
    static TEACHERS: OnceLock<Arc<RwLock<Vec<bool>>>> = OnceLock::new();
    TEACHERS.get_or_init(|| Arc::new(RwLock::new(vec![false; filtered_classrooms().read().len()])))
}
pub fn classrooms_acts() -> &'static Arc<RwLock<BTreeMap<i32, Vec<Activity>>>> {
    static CLASSES: OnceLock<Arc<RwLock<BTreeMap<i32, Vec<Activity>>>>> = OnceLock::new();
    CLASSES.get_or_init(|| Arc::new(RwLock::new(create_classrooms_acts())))
}

pub fn create_classrooms_acts() -> BTreeMap<i32, Vec<Activity>> {
    let acts = &*activities().read();
    let mut map = BTreeMap::new();
    for c in &*get_classrooms().read() {
        let mut c_acts = acts
            // .clone()
            .values()
            .filter(|a| a.classes.iter().any(|ac| ac == &c.1.id))
            .map(|a| a.clone())
            .collect::<Vec<Activity>>();
        c_acts.sort_by(|a, b| a.lecture.cmp(&b.lecture));
        map.insert(c.1.id, c_acts);
    }
    map
}
pub fn classroom_name() -> &'static Arc<RwLock<String>> {
    static NAME: OnceLock<Arc<RwLock<String>>> = OnceLock::new();
    NAME.get_or_init(|| Arc::new(RwLock::new("".to_string())))
}
fn classroom_short_name() -> &'static Arc<RwLock<String>> {
    static SHORT_NAME: OnceLock<Arc<RwLock<String>>> = OnceLock::new();
    SHORT_NAME.get_or_init(|| Arc::new(RwLock::new("".to_string())))
}
pub fn set_selected_classroom(id: i32) {
    let class = Arc::clone(selected_classroom());
    std::thread::spawn(move || {
        *class.write() = Some(id);
    });
}
pub fn classrooms_page(ui: &mut eframe::egui::Ui) {
    // let mut name = get_name().lock().unwrap();
    ui.vertical_centered(|ui| {
        ui.add_sized(
            vec2(250., 30.),
            TextEdit::singleline(&mut *classroom_name().write()).hint_text("Derslik Adını Gir"),
        );
        ui.add_sized(
            vec2(250., 30.),
            TextEdit::singleline(&mut *classroom_short_name().write()).hint_text("Kısa Adı"),
        );
        if ui.add_sized(vec2(250., 30.), Button::new("Ekle")).clicked() {
            add_classroom();
        }
    });
    ui.separator();
    flex_classes_ui(ui);
}

fn flex_classes_ui(ui: &mut eframe::egui::Ui) {
    Flex::horizontal()
        .gap(vec2(20., 20.))
        .wrap(true)
        .show(ui, |flex| {
            let del_states = del_classrooms_state().read().clone();
            let del_states = del_states.iter().enumerate();
            for (del_state, cl) in zip(del_states, filtered_classrooms().read().iter()) {
                let frame = egui::Frame::default()
                    .stroke(Stroke::new(0.3, Color32::GRAY))
                    .rounding(5.)
                    .inner_margin(5.);
                flex.add_flex(
                    item().grow(1.).frame(frame),
                    Flex::vertical().align_items_content(Align2::CENTER_TOP),
                    |flex| {
                        flex.add(item(), Label::new(&cl.name));
                        if *del_state.1 {
                            flex.add_flex(
                                item().grow(1.),
                                Flex::horizontal()
                                    .align_items(egui_flex::FlexAlign::Center)
                                    .wrap(false),
                                |flex| {
                                    if flex
                                        .add(
                                            item(),
                                            Link::new(RichText::new("Sil").color(Color32::RED)),
                                        )
                                        // .inner
                                        .clicked()
                                    {
                                        del_classroom(cl.id, del_state.0);
                                        // del_teacher(teacher.id);
                                    };
                                    if flex
                                        .add(item().grow(1.), Link::new("Vazgeç"))
                                        // .inner
                                        .clicked()
                                    {
                                        std::thread::spawn(move || {
                                            if let Some(state) =
                                                del_classrooms_state().write().get_mut(del_state.0)
                                            {
                                                *state = false;
                                            }
                                        });
                                    };
                                },
                            );
                        } else if flex
                            .add(
                                item().grow(1.),
                                Link::new(RichText::new("Sil").color(Color32::DARK_RED)),
                            )
                            // .inner
                            .clicked()
                        {
                            std::thread::spawn(move || {
                                if let Some(state) =
                                    del_classrooms_state().write().get_mut(del_state.0)
                                {
                                    *state = true;
                                }
                            });
                            // del_teacher(teacher.id);
                        }
                    },
                );
            }
        });
}
pub fn classrooms_lists_ui(ui: &mut eframe::egui::Ui) {
    ScrollArea::vertical().show(ui, |ui| {
        ui.add_space(30.);
        ui.separator();
        ui.vertical_centered(|ui| {
            if ui
                .add_sized(
                    vec2(250., 30.),
                    TextEdit::singleline(&mut *classroom_name().write()).hint_text("Filtrele"),
                )
                .changed()
            {
                set_classrooms_filter();
            };
            let mut classes = filtered_classrooms().write();
            for c in &mut *classes {
                let fill_color = if selected_classroom().read().is_some_and(|i| i == c.id) {
                    Color32::BLUE
                } else {
                    Color32::default()
                };
                let stroke_color = if selected_classroom().read().is_some_and(|i| i == c.id) {
                    Color32::LIGHT_BLUE
                } else {
                    Color32::LIGHT_GRAY
                };
                let button = egui::Frame::none()
                    .fill(fill_color)
                    .inner_margin(10.)
                    .outer_margin(2.)
                    .rounding(5.0)
                    .stroke(Stroke::new(1., stroke_color))
                    .show(ui, |ui| {
                        ui.label(&c.name);
                    })
                    .response;
                let button = button
                    .interact(egui::Sense::click())
                    .on_hover_cursor(egui::CursorIcon::PointingHand);
                if button.clicked() {
                    set_selected_classroom(c.id);
                }
            }
        });
    });
}

fn save_classrooms() {
    let classes = get_classrooms().read();
    let js = serde_json::to_string(&*classes);
    match js {
        Ok(j) => {
            let mut f = File::create("./db/classrooms.json").unwrap();
            f.write_all(j.as_bytes()).unwrap();
        }
        Err(_) => {}
    }
}
fn read_classrooms() -> BTreeMap<i32, ClassRoom> {
    let f = File::open("./db/classrooms.json");
    if let Ok(mut f) = f {
        let mut content: String = String::new();
        f.read_to_string(&mut content).unwrap();
        let cls: BTreeMap<i32, ClassRoom> = serde_json::from_str(content.as_str()).unwrap();
        return cls;
        // return BTreeMap::from_iter(cls.iter().map(|c| (c.id, c.clone())));
    }
    // validates_c_lims();
    BTreeMap::new()
}

fn add_classroom() {
    std::thread::spawn(move || {
        let len = find_new_id();
        let class = ClassRoom {
            id: len,
            name: classroom_name().write().clone(),
            short_name: classroom_short_name().write().clone(),
        };
        let mut cls = get_classrooms().write();
        cls.insert(len, class);
        drop(cls);
        *filtered_classrooms().write() = filtering_classrooms();
        // let c_lims = ClassLimitation::new(len);
        // classes_limitations().write().insert(len, c_lims);
        // save_classes_limitations();
        save_classrooms();
    });
}

fn del_classroom(index: i32, state: usize) {
    let classes = get_classrooms().clone();
    std::thread::spawn(move || {
        let cls = Arc::clone(&classes);
        cls.write().remove(&index);
        *filtered_classrooms().write() = filtering_classrooms();
        // classes_limitations().write().remove(&index);
        // save_classes_limitations();
        let acts = &mut *activities().write();
        acts.iter_mut()
            .for_each(|a| a.1.classes.retain(|c| c != &index));
        acts.retain(|_, a| !a.classes.is_empty());
        save_activities();
        std::thread::spawn(move || {
            // *classes_sched().write() = create_classes_sched();
            // *classes_acts().write() = create_classes_acts();
            // *().write() = create_teacher_acts();
        });
        del_classrooms_state().write().remove(state);
    });
    del_classrooms_acts(index);
    save_classrooms();
}
fn del_classrooms_acts(index: i32) {
    let acts = &mut *activities().write();
    if let Some(c_acts) = classrooms_acts().read().get(&index) {
        for a in c_acts {
            acts.remove(&a.id);
        }
    }
    classrooms_acts().write().remove(&index);
    save_activities();
}
fn find_new_id() -> i32 {
    let len = get_classrooms().read().len() as i32;
    for i in 1..len + 1 {
        if !get_classrooms().read().contains_key(&i) {
            return i;
        }
    }
    len + 1
}

// pub fn validates_c_lims() {
//     std::thread::spawn(move || {
//         let classes = &*get_classrooms().read();
//         // let lims = &mut *classes_limitations().write();
//         // lims.retain(|id, _lim| classes.contains_key(id));
//         // save_classes_limitations();
//         // validates_t_lims();
//     });
// }
// pub fn validates_t_lims() {
//     std::thread::spawn(move || {
//         let teachers = &*get_teachers().read();
//         let lims = &mut *teachers_limitations().write();
//         lims.retain(|id, _lim| teachers.contains_key(id));
//         save_teachers_limitations();
//         validates_c_acts();
//     });
// }
// fn validates_trlims() {
//     let teachers = &*get_classrooms().read();
//     let lims = &mut *classr_limitations().write();
//     lims.retain(|id, _lim| teachers.contains_key(id));
//     save_teachers_limitations();
// }
// pub fn validates_c_acts() {
//     std::thread::spawn(move || {
//         let classes = &*get_classes().read();
//         let acts = &mut *activities().write();
//         acts.retain(|_id, act| act.classes.iter().all(|ac| classes.contains_key(ac)));
//         save_activities();
//         validates_t_acts();
//     });
// }
// pub fn validates_t_acts() {
//     std::thread::spawn(move || {
//         let teachers = &*get_teachers().read();
//         let acts = &mut *activities().write();
//         acts.retain(|_id, act| act.teachers.iter().all(|ac| teachers.contains_key(ac)));
//         save_activities();
//         validates_l_acts();
//     });
// }
// pub fn validates_l_acts() {
//     std::thread::spawn(move || {
//         let lectures = &*get_lectures().read();
//         let acts = &mut *activities().write();
//         acts.retain(|_id, act| lectures.contains_key(&act.lecture));
//         save_activities();
//     });
// }