use reqwest_cookie_store::{CookieStore, CookieStoreMutex};
use serde::*;
use slint::{ComponentHandle, ModelRc, VecModel};
use std::{fs::remove_file, io::Write, rc::Rc, sync::Arc};
slint::include_modules!();
fn cookie_store(my_app: &MyApp) -> CookieStore {
    let cookie_store = {
        let file = std::fs::File::open("cookie.json").map(std::io::BufReader::new);
        match file {
            Ok(f) => {
                // serde_json::from_str::<CookieStore>(&f).unwrap();
                my_app.global::<Data>().set_logged(true);
                CookieStore::load_json(f).unwrap()
                // CookieStore::new(None)
            }
            Err(_) => CookieStore::new(None),
        }
        // use re-exported version of `CookieStore` for crate compatibility
    };
    cookie_store
}
fn load_user(my_app: &MyApp) {
    let _ = {
        let file = std::fs::read_to_string("user.json");
        match file {
            Ok(f) => {
                let f = serde_json::from_str::<User>(&f).unwrap();
                my_app.global::<Data>().set_user(SlintUser {
                    id: f.id,
                    first_name: f.first_name.into(),
                    mail: f.email.into(),
                });
                // CookieStore::new(None)
            }
            Err(_) => (),
        }
        // use re-exported version of `CookieStore` for crate compatibility
    };
}
pub fn ui() {
    let window = MyApp::new().unwrap();
    let w_window = window.as_weak().unwrap();
    let w_window2 = w_window.as_weak().unwrap();
    let cookie_store = cookie_store(&window).clone();
    let _ = load_user(&window);
    let cookie_store2 = cookie_store.clone();
    window.global::<Callbacks>().on_logout(move || {
        remove_file("./cookie.json").expect("Dosya silinemedi");
        remove_file("./user.json").expect("Dosya silinemedi");
    });
    window.global::<Callbacks>().on_login(move || {
        let form = LoginForm {
            email: w_window.global::<LForm>().get_email().to_string(),
            password: w_window.global::<LForm>().get_password().to_string(),
        };
        let w_window = w_window.as_weak().unwrap();
        // let cookie_store = cookie_store.clone();
        slint::spawn_local(async move {
            let rt = tokio::runtime::Runtime::new().unwrap();
            let res = rt
                .spawn(async move {
                    let res = login(form).await;
                    res
                })
                .await
                .unwrap();
            w_window.global::<Data>().set_user(SlintUser {
                id: res.id,
                first_name: res.first_name.into(),
                mail: res.email.into(),
            });
            w_window.global::<Data>().set_logged(true);
            let res = rt
                .spawn(async move {
                    let cs = {
                        let file = std::fs::File::open("cookie.json").map(std::io::BufReader::new);
                        match file {
                            Ok(f) => CookieStore::load_json(f).unwrap(),
                            Err(_) => CookieStore::default(),
                        }
                    };
                    let r = get_school(cs).await;
                    r
                })
                .await
                .unwrap();
            let schools = VecModel::from(vec![]);
            for s in res {
                let school = SSchool {
                    id: s.id,
                    name: s.name.into(),
                };
                schools.push(school);
            }
            let ssi: Rc<VecModel<SSchool>> = Rc::new(schools);
            let schools = ModelRc::from(ssi);
            w_window.global::<Data>().set_schools(schools);
        })
        .expect("Hata");
        // .unwrap();
    });
    window.global::<Callbacks>().on_get_key(move || {
        let w_window = w_window2.as_weak().unwrap();
        let cookie_store = cookie_store2.clone();
        slint::spawn_local(async move {
            let rt = tokio::runtime::Runtime::new().unwrap();
            let res = rt
                .spawn(async move {
                    let res =
                        get_key(std::sync::Arc::new(CookieStoreMutex::new(cookie_store))).await;
                    res
                })
                .await
                .unwrap();
            println!("{res:?}");
            w_window.global::<Data>().set_key(res.into());
            rt.spawn(async move {})
            // w_window.global::<User>().set_first_name(res.into());
        })
        .expect("Hata");
    });
    window.run().unwrap();
}
// use jni::*;
async fn login(form: LoginForm) -> User {
    // let c = jni::
    let cookie_store = CookieStore::new(None);
    let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookie_store);
    let cookie_store = std::sync::Arc::new(cookie_store);
    let cl = reqwest::Client::builder()
        // .cookie_store(true)
        .cookie_provider(std::sync::Arc::clone(&cookie_store))
        .build()
        .unwrap();
    let res = cl
        .post("http://192.168.1.101/login")
        .json(&form)
        .send()
        .await
        .unwrap();
    let a = res.text().await.unwrap();
    {
        let mut writer: std::io::BufWriter<std::fs::File> = std::fs::File::create("cookie.json")
            .map(std::io::BufWriter::new)
            .unwrap();
        let store = cookie_store.lock().unwrap();
        store.save_json(&mut writer).unwrap();

        let mut writer: std::io::BufWriter<std::fs::File> = std::fs::File::create("user.json")
            .map(std::io::BufWriter::new)
            .unwrap();
        writer.write_all(&a.as_bytes()).unwrap();
        writer.flush().unwrap();
    }
    // writer.flush().unwrap();
    serde_json::from_str(&a).unwrap()
}
async fn get_key(cookie_store: Arc<CookieStoreMutex>) -> String {
    let cl = reqwest::Client::builder()
        // .cookie_store(true)
        .cookie_provider(std::sync::Arc::clone(&cookie_store))
        .build()
        .unwrap();
    let _res = cl
        .get("http://192.168.1.101/get_key/1")
        .send()
        .await
        .unwrap()
        .text()
        .await
        .unwrap();
    _res
}
async fn get_school(cookie_store: CookieStore) -> Vec<School> {
    let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookie_store);
    let cookie_store = std::sync::Arc::new(cookie_store);
    let cl = reqwest::Client::builder()
        // .cookie_store(true)
        .cookie_provider(std::sync::Arc::clone(&cookie_store))
        .build()
        .unwrap();
    let _res = cl
        .get("http://192.168.1.101/schools")
        .send()
        .await
        .unwrap()
        .json::<Vec<School>>()
        .await
        .unwrap();
    _res
}
#[derive(Serialize, Deserialize)]
struct LoginForm {
    email: String,
    password: String,
}
#[derive(Serialize, Deserialize)]
struct User {
    id: i32,
    email: String,
    first_name: String,
}
#[derive(Serialize, Deserialize, Clone)]
struct School {
    id: i32,
    name: String,
}