use crate::online_classroom::register_course::register_course;
use crate::online_classroom::update_expiration_date::update_expiration_date;
use crate::{
    json_result::JsonResult,
    model::{
        classroom_user::{ClassroomCourseRegistration, ClassroomPersonCreate},
        person::PersonLink,
    },
    online_classroom::{create_user::create, get_courses::ClassroomCourse},
};
use rocket::{http::Status, serde::json::Json};

#[options("/classroom/user")]
pub fn create_user_options() -> Status {
    Status::Ok
}

#[post("/classroom/user", format = "json", data = "<data>")]
pub async fn create_user(
    data: Json<ClassroomPersonCreate>,
) -> (Status, Json<JsonResult<PersonLink>>) {
    match create(&data.0).await {
        Ok(p) => (Status::Ok, JsonResult::ok(p)),
        Err(err) => (Status::InternalServerError, JsonResult::err(err)),
    }
}

#[get("/classroom/course/<user_id>")]
pub async fn get_courses(user_id: i32) -> (Status, Json<JsonResult<Vec<ClassroomCourse>>>) {
    match crate::online_classroom::get_courses::get_courses(user_id).await {
        Ok(courses) => (Status::Ok, JsonResult::ok(courses)),
        Err(err) => (Status::InternalServerError, JsonResult::err(err)),
    }
}

#[options("/classroom/course/<_u>")]
pub fn register_course_contr_options(_u: i32) -> Status {
    Status::Ok
}

#[post("/classroom/course/<user_id>", format = "json", data = "<data>")]
pub async fn register_course_contr(
    user_id: i32,
    data: Json<ClassroomCourseRegistration>,
) -> (Status, Json<JsonResult<()>>) {
    match register_course(user_id, &data.surname_first_letter, &data.courses).await {
        Ok(()) => (Status::Ok, JsonResult::ok(())),
        Err(err) => (Status::InternalServerError, JsonResult::err(err)),
    }
}

#[get("/classroom/expiration_date/<user_id>")]
pub async fn get_expiration_date(user_id: i32) -> (Status, Json<JsonResult<String>>) {
    match crate::online_classroom::get_expiration_date::get_expiration_date(user_id).await {
        Ok(date) => (Status::Ok, JsonResult::ok(date)),
        Err(err) => (Status::InternalServerError, JsonResult::err(err)),
    }
}

//
//  Set expiration date
//

#[derive(Debug, serde::Deserialize)]
pub struct ExpirationDate {
    pub date: String,
}

#[options("/classroom/expiration_date/<_u>")]
pub async fn set_expiration_date_options(_u: i32) -> Status {
    Status::Ok
}

#[put(
    "/classroom/expiration_date/<user_id>",
    format = "json",
    data = "<data>"
)]
pub async fn set_expiration_date(
    user_id: i32,
    data: Json<ExpirationDate>,
) -> (Status, Json<JsonResult<()>>) {
    match update_expiration_date(user_id, data.date.clone()).await {
        Ok(()) => (Status::Ok, JsonResult::ok(())),
        Err(err) => (Status::InternalServerError, JsonResult::err(err)),
    }
}
