/*
 * authservice process/profile.rs
 * - "customization-related" request functions
 *
 * Copyright (C) 2025 Real Microsoft, LLC
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

use asklyphe_common::nats::authservice::{AuthError, AuthResponse};
use asklyphe_common::nats::authservice::profile::{ThemeChangeRequest, ThemeChangeResponse, UserInfo, UserInfoRequest, UserInfoResponse};
use sea_orm::DatabaseConnection;
use crate::db::{session, user, usersettings};
use crate::db::session::FetchSessionError;
use crate::db::user::FetchUserError;
use crate::db::usersettings::{FetchUserSettingsError, UserSettings};

pub async fn user_info(db: &DatabaseConnection, request: UserInfoRequest) -> UserInfoResponse {
    let uid = match session::get_userid_from_session(db, request.token, true).await {
        Ok(u) => u,
        Err(e) => {
            return match e {
                FetchSessionError::SessionInvalid => {
                    UserInfoResponse::TokenExpired
                }
                FetchSessionError::SessionDoesntExist => {
                    UserInfoResponse::TokenInvalid
                }
                FetchSessionError::DatabaseError => {
                    UserInfoResponse::InternalServerError("database error while querying user id".to_string())
                }
            };
        }
    };

    let user_info = match user::user_info(db, uid.clone()).await {
        Ok(u) => u,
        Err(e) => return match e {
            FetchUserError::UserNotFound => {
                UserInfoResponse::TokenInvalid
            }
            FetchUserError::DatabaseError => {
                UserInfoResponse::InternalServerError("database error while querying user id".to_string())
            }
        }
    };
    
    let user_settings = match usersettings::get_or_create_default_user_settings(db, uid).await {
        Ok(u) => u,
        Err(e) => return match e {
            FetchUserSettingsError::UserNotFound => {
                UserInfoResponse::InternalServerError("database error while querying user id".to_string())
            }
            FetchUserSettingsError::DatabaseError => {
                UserInfoResponse::InternalServerError("database error while querying user id".to_string())
            }
        }
    };
    
    UserInfoResponse::Success(UserInfo {
        username: user_info.username,
        email: user_info.email,
        new_email: user_info.new_email,
        theme: user_settings.theme,
        administrator: user_info.admin,
    })
}

pub async fn change_theme(db: &DatabaseConnection, request: ThemeChangeRequest) -> ThemeChangeResponse {
    let uid = match session::get_userid_from_session(db, request.token, true).await {
        Ok(u) => u,
        Err(e) => {
            return match e {
                FetchSessionError::SessionInvalid => {
                    ThemeChangeResponse::Logout
                }
                FetchSessionError::SessionDoesntExist => {
                    ThemeChangeResponse::Logout
                }
                FetchSessionError::DatabaseError => {
                    ThemeChangeResponse::InternalServerError
                }
            };
        }
    };
    match usersettings::set_theme(db, uid, request.theme).await {
        Ok(_) => {
            ThemeChangeResponse::Success
        }
        Err(e) => {
            match e {
                FetchUserSettingsError::UserNotFound => {
                    ThemeChangeResponse::Logout
                }
                FetchUserSettingsError::DatabaseError => {
                    ThemeChangeResponse::InternalServerError
                }
            }
        }
    }
}