use super::session::{create_user_request, request};
use crate::model::{classroom_user::ClassroomPersonCreate, person::PersonLink};
use scraper::{Html, Selector};

const CREATION_ERR: &str = "Creation successful, but linking failed";

/// Creates an online classroom user
pub async fn create(data: &ClassroomPersonCreate) -> Result<PersonLink, String> {
    let sec_token = get_form_sec_token().await?;

    let body = get_request_body(
        &data.person_surnames,
        &data.person_names,
        &data.person_email,
        &data.person_username,
        &data.person_password,
        &data.person_expiration_date,
        &sec_token,
    );

    // Do create
    let response = create_user_request("/main/admin/user_add.php".into(), body).await?;

    if response.is_empty() {
        // User created successfully.
        // Have to find its user_id, and link it to the person
        let users = super::user::get_users_impl(data.person_username.clone()).await;

        match users {
            Ok(user) if user.len() == 1 => {
                let user_id: i32 = user[0].user_id.parse().or_else(|err| {
                    Err(format!(
                        "{}: Error parsing user_id: {:?}",
                        CREATION_ERR, err
                    ))
                })?;

                let person_link = PersonLink {
                    person_id: data.person_id,
                    person_classroom_id: user_id,
                    person_classroom_username: data.person_username.clone(),
                };
                let result = person_link.insert().await;

                match result {
                    Ok(_) => return Ok(person_link),
                    Err(reason) => return Err(format!("{}: {}", CREATION_ERR, reason)),
                }
            }
            Ok(u) if u.is_empty() => {
                return Err(format!(
                    "{}: No users with username {} found",
                    CREATION_ERR, data.person_username
                ))
            }
            Ok(_) => return Err(format!("{}: More than 1 user found", CREATION_ERR)),
            Err(reason) => return Err(format!("{}: {}", CREATION_ERR, reason)),
        }
    }

    Err("Expected empty body, found something else".into())
}


/// Makes a request to the user creation form, and gets the
/// security token.
/// 
/// This security token must be present for CSRF reasons
async fn get_form_sec_token() -> Result<String, String> {
    let creation_form = request("/main/admin/user_add.php".into()).await?;

    let sec_token_selector = Selector::parse("#user_add_sec_token")
        .or_else(|err| Err(format!("Error creating sec_token selector: {:?}", err)))?;

    let fragment = Html::parse_document(&creation_form);

    let input_element = match fragment.select(&sec_token_selector).next() {
        Some(el) => el,
        None => return Err(format!("Error selecting sec_token element. Not found")),
    };

    let sec_token_value = match input_element.value().attr("value") {
        Some(val) => val,
        None => {
            return Err(format!(
                "Error getting sec_token value from input. Not found"
            ))
        }
    };

    Ok(sec_token_value.into())
}


/// Creates a request body data to send to the classroom
fn get_request_body(
    surnames: &String,
    names: &String,
    email: &String,
    username: &String,
    password: &String,
    expiration_date: &String,
    sec_token: &String,
) -> String {
    format!(
        r#"
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="lastname"

{surnames}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="firstname"

{names}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="official_code"

{password}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="email"

{email}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="phone"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="picture"; filename=""
Content-Type: application/octet-stream


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="username"

{username}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="password[password_auto]"

0
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="password[password]"

{password}
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="status"

5
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="admin[platform_admin]"

0
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="language"

spanish
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="mail[send_mail]"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="radio_expiration_date"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="expiration_date"

{expiration_date} 23:59
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="active"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_legal_accept"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_already_logged_in"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_update_type"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_rssfeeds"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_dashboard"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_timezone"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_mail_notify_invitation"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_mail_notify_message"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_mail_notify_group_message"

1
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_user_chat_status"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_google_calendar_url"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_captcha_blocked_until_date"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_skype"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_linkedin_url"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_request_for_legal_agreement_consent_removal_justification"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_request_for_delete_account_justification"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_request_for_legal_agreement_consent_removal"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="extra_request_for_delete_account"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="submit"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="_qf__user_add"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="MAX_FILE_SIZE"

536870912
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="picture_crop_result"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="picture_crop_image_base_64"


-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="item_id"

0
-----------------------------83919643214156711801978607619
Content-Disposition: form-data; name="sec_token"

{sec_token}
-----------------------------83919643214156711801978607619--
"#
    )
}
