use eframe::egui;
use eframe::egui::mutex::RwLock;
use eframe::egui::vec2;
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 super::activities::activities;
use super::activities::activity_form::act_teachers;
use super::activities::activity_form::filtered_teachers;
// use super::activities::activity_form::filtered_teachers;
use super::activities::activity_form::teachers_ui::set_teachers_filter;
use super::activities::save_activities;
use super::activities::Activity;
use super::limitations::limitations_ui::create_teachers_sched;
use super::limitations::limitations_ui::save_teachers_limitations;
use super::limitations::limitations_ui::teachers_limitations;
use super::limitations::limitations_ui::teachers_scheds;
use super::limitations::limitations_ui::TeacherLimitation;

#[derive(Clone, Serialize, Deserialize)]
pub struct Teacher {
    pub id: i32,
    pub name: String,
    pub short_name: String,
}
pub fn selected_teacher() -> &'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_teachers() -> &'static Arc<RwLock<BTreeMap<i32, Teacher>>> {
    static TEACHERS: OnceLock<Arc<RwLock<BTreeMap<i32, Teacher>>>> = OnceLock::new();
    TEACHERS.get_or_init(|| Arc::new(RwLock::new(read_teachers())))
}
pub fn del_teachers_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_teachers().read().len()])))
}
pub fn teachers_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_teacher_acts())))
}

pub fn create_teacher_acts() -> BTreeMap<i32, Vec<Activity>> {
    let acts = &*activities().read();
    let mut map = BTreeMap::new();
    for t in &*get_teachers().read() {
        let mut c_acts = acts
            // .clone()
            .values()
            .filter(|a| {
                a.teachers.iter().any(|ac| ac == &t.1.id)
                    || a.teachers.is_empty()
                    || a.classes.is_empty()
            })
            .map(|a| a.clone())
            .collect::<Vec<Activity>>();
        c_acts.sort_by(|a, b| a.lecture.cmp(&b.lecture));
        map.insert(t.1.id, c_acts);
    }
    map
}
pub fn teacher_name() -> &'static Arc<RwLock<String>> {
    static NAME: OnceLock<Arc<RwLock<String>>> = OnceLock::new();
    NAME.get_or_init(|| Arc::new(RwLock::new("".to_string())))
}
fn teacher_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())))
}
fn update_teacher_form() -> &'static Arc<RwLock<bool>> {
    static SHORT_NAME: OnceLock<Arc<RwLock<bool>>> = OnceLock::new();
    SHORT_NAME.get_or_init(|| Arc::new(RwLock::new(false)))
}
fn update_teacher(ui: &mut eframe::egui::Ui) {
    egui::Window::new("Select Teacher")
        .open(&mut *update_teacher_form().write())
        .resizable([true, true])
        .show(ui.ctx(), |ui| {
            ui.add(TextEdit::singleline(&mut *teacher_name().write()));
            ui.add(TextEdit::singleline(&mut *teacher_short_name().write()));
            if ui.add(Button::new("Güncelle")).clicked() {
                if let Some(t) = get_teachers()
                    .write()
                    .get_mut(&selected_teacher().read().unwrap())
                {
                    t.name = teacher_name().read().clone();
                    t.short_name = teacher_short_name().read().clone();
                    save_teachers();
                }
            }
        });
}
pub fn teachers_page(ui: &mut eframe::egui::Ui) {
    // let mut name = get_name().lock().unwrap();
    ui.vertical_centered(|ui| {
        if ui
            .add_sized(
                vec2(250., 30.),
                TextEdit::singleline(&mut *teacher_name().write())
                    .hint_text("Öğretmenin Adı ve Soyadı"),
            )
            .changed()
        {
            set_teachers_filter();
        };
        if ui
            .add_sized(
                vec2(250., 30.),
                TextEdit::singleline(&mut *teacher_short_name().write()).hint_text("Kısa Ad"),
            )
            .changed()
        {};
        if ui
            .add_sized(vec2(250., 30.), Button::new("Öğretmeni Ekle"))
            .clicked()
        {
            add_teacher();
            save_teachers();
        }
    });
    ui.separator();
    teachers_ui(ui);
}

pub fn teachers_list_ui(ui: &mut 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 *teacher_name().write()).hint_text("Filtrele"),
                )
                .changed()
            {
                set_teachers_filter();
            };
            let mut teachers = filtered_teachers().write();
            for c in &mut *teachers {
                let fill_color = if selected_teacher().read().is_some_and(|i| i == c.id) {
                    Color32::BLUE
                } else {
                    Color32::default()
                };
                let stroke_color = if selected_teacher().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_teacher(c.clone());
                }
            }
        });
    });
}
pub fn teachers_ui(ui: &mut eframe::egui::Ui) {
    update_teacher(ui);
    Flex::horizontal()
        .gap(vec2(20., 20.))
        .wrap(true)
        .show(ui, |flex| {
            let del_states = del_teachers_state().read().clone();
            let del_states = del_states.iter().enumerate();
            for (del_state, teacher) in zip(del_states, filtered_teachers().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(), |flex| {
                    flex.add(item(), Label::new(&teacher.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_teacher(teacher.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_teachers_state().write().get_mut(del_state.0)
                                        {
                                            *state = false;
                                        }
                                    });
                                };
                            },
                        );
                    } else {
                        flex.ui().layout().horizontal_justify();
                        flex.add_flex(
                            item().grow(0.0),
                            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()
                                {
                                    std::thread::spawn(move || {
                                        if let Some(state) =
                                            del_teachers_state().write().get_mut(del_state.0)
                                        {
                                            *state = true;
                                        }
                                    });
                                };
                                if flex
                                    .add(item().grow(1.), Link::new("Düzenle"))
                                    // .inner
                                    .clicked()
                                {
                                    let t = teacher.clone();
                                    set_selected_teacher(t.clone());
                                    std::thread::spawn(move || {
                                        *teacher_name().write() = t.name.clone();
                                        *teacher_short_name().write() = t.short_name.clone();
                                        *update_teacher_form().write() = true;
                                    });
                                };
                            },
                        );
                    }
                });
            }
        });
}

fn save_teachers() {
    std::thread::spawn(move || {
        let teachers = get_teachers().read();
        let js = serde_json::to_string(&*teachers);
        match js {
            Ok(j) => {
                let mut f = File::create("./db/teachers.json").unwrap();
                f.write_all(j.as_bytes()).unwrap();
            }
            Err(_) => {}
        }
    });
}
fn add_teacher() {
    let id = find_new_id();
    let teacher = Teacher {
        id,
        name: teacher_name().read().clone(),
        short_name: teacher_short_name().read().clone(),
    };
    get_teachers().write().insert(id, teacher);
    *teacher_name().write() = "".to_string();
    *teacher_short_name().write() = "".to_string();
    set_teachers_filter();
    let t_lims = TeacherLimitation::new(id);
    teachers_limitations().write().insert(id, t_lims);
    save_teachers();
    save_teachers_limitations();
    del_teachers_state().write().push(false);
}
fn read_teachers() -> BTreeMap<i32, Teacher> {
    let f = File::open("./db/teachers.json");
    if let Ok(mut f) = f {
        let mut content: String = String::new();
        f.read_to_string(&mut content).unwrap();
        let cls: BTreeMap<i32, Teacher> = serde_json::from_str(content.as_str()).unwrap();
        return cls;
    }
    BTreeMap::new()
}

fn del_teacher(id: i32, state: usize) {
    // let cls = Arc::clone(&teachers);
    std::thread::spawn(move || {
        get_teachers().write().remove(&id);
        save_teachers();
        del_teacher_acts(id);
        teachers_limitations().write().remove(&id);
        save_teachers_limitations();
        *teachers_scheds().write() = create_teachers_sched();
        teachers_acts().write().remove(&id);
        set_teachers_filter();
        del_teachers_state().write().remove(state);
    })
    .join()
    .unwrap();
}
fn del_teacher_acts(id: i32) {
    // let acts = &mut *activities().write();
    if let Some(c_acts) = teachers_acts().read().get(&id) {
        for a in c_acts {
            if a.teachers.iter().any(|t| t == &id) {
                activities().write().remove(&a.id);
            }
        }
    }
    teachers_acts().write().remove(&id);
    save_activities();
}
fn find_new_id() -> i32 {
    let len = get_teachers().read().len() as i32;
    for i in 1..len + 1 {
        if !get_teachers().read().contains_key(&i) {
            return i;
        }
    }
    len + 1
}
pub fn set_selected_teacher(t: Teacher) {
    let teacher = Arc::clone(selected_teacher());
    std::thread::spawn(move || {
        *teacher.write() = Some(t.id);
    });
    // let lims = teachers_limitations().read();
    // let lims = lims.get(&t.id);
    // match lims {
    //     Some(lims) => {
    //         *teacher_limitation().write() = lims.clone();
    //     }
    //     None => {
    //         *teacher_limitation().write() = TeacherLimitation::new(t.id);
    //     }
    // }
    *act_teachers().write() = vec![t.clone()];
}