use std::sync::Arc;
use axum::{
    http::{
        StatusCode,
        Uri,
        header::HeaderMap,
    },
    Json,
    routing::{get,post},
    Extension,
    extract::ConnectInfo,
    response::{IntoResponse,Response,Redirect},
    Router,
};
use tower_cookies::Cookies;

use crate::{
    route,
    defs::{
        AppDBs,
        Random,
        ReqHandler,
        ReqHeaderMap,
        AppConnectInfo, TraceData,
        AuthState,
    },
    users::{
        User,
        UserItem,
        UserStatus,
        AllUserData,
    },
    handlers::{
        add_session_cookie,
        get_auth_state,
    },
};
use crate::users::OpenidUser;

pub fn is_allowed(auth_state: &AuthState,auth_roles: &Vec<String>, req_handler: &ReqHandler) -> bool {
    if ! auth_state.has_auth_role(&auth_roles) {
        let _ = req_handler.trace_req(format!("Req: {} User '{}' not have role 'dev'", &req_handler.req_name, &auth_state.user_id()));
        return false;
    }
    true
}
pub fn admin_router_handlers() -> Router {
    async fn users_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let mut req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "users_handler"
        );
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let users = match User::list(&app_dbs.user_store, true, false, "").await {
            Ok(data) => data,
            Err(e) => {
                let _ = req_handler.trace_req(format!("Error list users: {}",e));
                println!("Error list users: {}",e);
                Vec::new()
            },
        };
        req_handler.context.insert("users", &users);
        let mut users_openids = Vec::new();
        for usr in users.iter() {
            let openid_sel = OpenidUser::list_selection(
                "userid", &usr.id.to_string(), &app_dbs.user_store, true,false, "|"
            ).await.unwrap_or_else(|e| {
                println!("Error list selection {}: {}", &usr.name, e);
                Vec::new()
            });
            users_openids.push(openid_sel.iter().map(|id| id.appkey.to_string()).collect::<Vec<String>>().join(","));
        }
        req_handler.context.insert("users_openids", &users_openids);
        req_handler.context.insert("total_usrs", &users.len());
        req_handler.context.insert("with_menu", "1");
        let mut res_headers = HeaderMap::new();
        if req_handler.req_header.is_browser() {
            res_headers.append(axum::http::header::CONTENT_TYPE,"text/html; charset=utf-8".parse().unwrap());
        }
        let result = if let Some(tpl) = app_dbs.config.tpls.get("users") {
            req_handler.render_template(&tpl,"Users")
        } else {
            String::from("Users")
        };
        let _ = req_handler.trace_req(format!("Render users list"));
        (
            res_headers,
            result 
        ).into_response()
    }
     async fn user_get_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_get_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
                StatusCode::UNAUTHORIZED,
                req_handler.req_header.header,
                "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            // User not exists
            let _ = req_handler.trace_req(format!("User '{}' = {}' not found",&user_item.name, &user_item.value));
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
        user_sel.password = String::from("");
        user_sel.otp_base32 = String::from("");
        let openid_sel = OpenidUser::list_selection(
      "userid", &user_sel.id.to_string(), &app_dbs.user_store, true,false, "|"
         ).await.unwrap_or_else(|e| {
            println!("Error list selection {}: {}", &user_sel.name, e);
            Vec::new()
         });
        let user_openids = openid_sel.iter().map(|id| id.appkey.to_string()).collect::<Vec<String>>().join(",");
        let str_user = serde_json::to_string(&user_sel).unwrap_or_else(|e|{
             let msg = format!("Error to convert user data items to json: {}",e);
             println!("{}", &msg);
             let _ = req_handler.trace_req(msg);
             String::from("")
        });
        let _ = req_handler.trace_req(format!("User: {} get data", &user_sel.id));
        let result = format!("{{\"user\": {}, \"openids\": \"{}\"}}",str_user, user_openids);
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn user_save_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(new_user): Json<AllUserData>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_save_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
                StatusCode::UNAUTHORIZED,
                req_handler.req_header.header,
                "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"text/plain; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let mut user_sel = User::select("id", &format!("{}",&new_user.user.id), false,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            // User not exists
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
        let new_id = new_user.user.id;
        user_sel.from_user(new_user.user);
        let user_data = user_sel.session_data();
        if user_sel.update(&app_dbs.user_store).await.is_err() {
            return (
                StatusCode::BAD_REQUEST,
                req_handler.req_header.header,
                "Error"
            ).into_response();
        }
        let session_token = req_handler.new_token();
        let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
        if app_dbs.config.verbose > 1 { println!("session cookie: {}", &session_cookie) };
        OpenidUser::sync_ids(&new_id.to_string(), &new_user.openids, &app_dbs.user_store).await;
        let result = String::from("Ok");
        (
            res_headers,
            result 
        ).into_response()
    }
     async fn user_delete_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_delete_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
                StatusCode::UNAUTHORIZED,
                req_handler.req_header.header,
                "Error"
           ).into_response();
        }
        // let req_handler = ReqHandler::new(
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
             let _ = req_handler.trace_req(format!("User '{}' not found",&user_id));
            // User not exists
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
       
        let result = match User::delete(user_sel.id,&app_dbs.user_store).await {
            Ok(val) => if val {
                let _ = req_handler.trace_req(format!("User '{}' delete",&user_id));
                OpenidUser::sync_ids(&user_sel.id.to_string(), "", &app_dbs.user_store).await;
                format!("Ok")
            } else {
                let _ = req_handler.trace_req(format!("Error delete user '{}'" ,&user_id));
                format!("Error user not deleted")
            },
            Err(e) => {
                let _ = req_handler.trace_req(format!("Delte user '{}' Error: {}",&user_id,e));
                println!("Error delete user: {}", e);
                format!("Error on delete user")
            }
        };
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn user_as_admin_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_as_admin_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
               StatusCode::UNAUTHORIZED,
               req_handler.req_header.header,
               "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            let _ = req_handler.trace_req(format!("User '{}' = '{}' not found",&user_item.name, &user_item.value));
            // User not exists
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
        let result = if user_sel.isadmin {
            let _ = req_handler.trace_req(format!("User '{}' already admin",&user_id));
            format!("User already admin")
        } else {
            user_sel.isadmin = true;
            let user_data = user_sel.session_data();
            match user_sel.update(&app_dbs.user_store).await {
                Ok(_) => {
                    let _ = req_handler.trace_req(format!("User '{}' updated",&user_id));
                    let session_token = req_handler.new_token();
                    let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
                    if app_dbs.config.verbose > 1 { println!("session cookie: {}", &session_cookie) };
                    String::from("Ok")
                },
                Err(e) => {
                    let _ = req_handler.trace_req(format!("User '{}' update error: {}",&user_id,e));
                    return (
                        StatusCode::BAD_REQUEST,
                        req_handler.req_header.header,
                        "Error"
                    ).into_response()
                }
            }

        };
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn user_disable_totp_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_disable_totp_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
                StatusCode::UNAUTHORIZED,
                req_handler.req_header.header,
                "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            // User not exists
            let _ = req_handler.trace_req(format!("User '{}' = '{}' not found",&user_item.name, &user_item.value));
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
        let result = if user_sel.otp_enabled && !user_sel.otp_base32.is_empty() {
            user_sel.disable_totp();
            let user_data = user_sel.session_data();
            match user_sel.update(&app_dbs.user_store).await {
                Ok(_) => {
                    let session_token = req_handler.new_token();
                    let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
                    if app_dbs.config.verbose > 1 { println!("session cookie: {}", &session_cookie) };
                    String::from("Ok")
                },
                Err(e) => {
                    let _ = req_handler.trace_req(format!("User '{}' = '{}' TOTP update error: {}",&user_item.name,&user_item.value,e)); 
                    return (
                        StatusCode::BAD_REQUEST,
                        req_handler.req_header.header,
                        "Error"
                    ).into_response();
                }
            }
        } else {
            let _ = req_handler.trace_req(format!("User '{}' TOTP no enabled",&user_sel.id)); 
            format!("User does not have TOTP enabled")
        };
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn user_passwd_reset_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "user_passwd_reset_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
                StatusCode::UNAUTHORIZED,
                req_handler.req_header.header,
                "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if !auth_state.is_admin() {
            let _ = req_handler.trace_req(format!("User: {} is not admin",auth_state.user_id()));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            // User not exists
            let _ = req_handler.trace_req(format!("User '{}' = '{}' not found",&user_item.name, &user_item.value));
            return (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error"
            ).into_response();
        }
        if user_sel.status != UserStatus::Active {
            let _ = req_handler.trace_req(format!("User '{}' is not '{}' state",&user_item.value, UserStatus::Active));
            (
                StatusCode::BAD_REQUEST,
                res_headers,
                "Error User not active !!"
            ).into_response()
        } else {
            user_sel.status = UserStatus::Pending;
            // TODO send email notification and redirect in login to completed pending task
            let user_data = user_sel.session_data();
            match user_sel.update(&app_dbs.user_store).await {
                Ok(_) => {
                    let session_token = req_handler.new_token();
                    let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
                    if app_dbs.config.verbose > 1 { println!("session cookie: {}", &session_cookie) };
                    let result = String::from("Ok");
                    (
                      res_headers,
                      result.to_owned()
                    ).into_response()
                },
                Err(e) => {
                    let _ = req_handler.trace_req(format!("User '{}' update error: {}",&user_item.value, e));
                    (
                       StatusCode::BAD_REQUEST,
                       req_handler.req_header.header,
                       "Error"
                    ).into_response()
                }
            }
        }
    }
    async fn logs_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let mut req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "log_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        if ! is_allowed(&auth_state,&app_dbs.config.auth_roles,&req_handler) {
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let mut res_headers = HeaderMap::new();
        if req_handler.req_header.is_browser() {
            res_headers.append(axum::http::header::CONTENT_TYPE,"text/html; charset=utf-8".parse().unwrap());
        }
        let logs = req_handler.logs("", true, true);
        let usr = User::default();
        req_handler.context.insert("user",&usr);
        req_handler.context.insert("logs", &logs);
        req_handler.context.insert("total_logs", &logs.len());
        req_handler.context.insert("with_menu", "1");
        let result = if let Some(tpl) = app_dbs.config.tpls.get("logs") {
            req_handler.render_template(&tpl,"Logs")
        } else {
            String::from("Logs")
        };
        // Turn off logging this here !!!
        // let _ = req_handler.trace_req(format!("Render logs"));
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn log_id_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        axum::extract::Path(userid): axum::extract::Path<String>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let mut req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "log_id_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        if ! is_allowed(&auth_state,&app_dbs.config.auth_roles,&req_handler) {
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let user_sel = User::select("id", &userid, true,&app_dbs.user_store).await.unwrap_or_default();
        if user_sel.name.is_empty() {
            // User not exists
            let _ = req_handler.trace_req(format!("User 'id' = '{}' not found",&userid));
            return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
        }
        let mut res_headers = HeaderMap::new();
        if req_handler.req_header.is_browser() {
            res_headers.append(axum::http::header::CONTENT_TYPE,"text/html; charset=utf-8".parse().unwrap());
        }
        let logs = req_handler.logs(&userid, true, true);
        req_handler.context.insert("user", &user_sel);
        req_handler.context.insert("logs", &logs);
        req_handler.context.insert("total_logs", &logs.len());
        req_handler.context.insert("with_menu", "1");
        let result = if let Some(tpl) = app_dbs.config.tpls.get("logs") {
            req_handler.render_template(&tpl,"Logs")
        } else {
            String::from("Logs")
        };
        // Turn off logging this here !!!
        // let _ = req_handler.trace_req(format!("Render logs id: {}", &userid));
        (
            res_headers,
            result.to_owned()
        ).into_response()
    }
    async fn log_delete_handler(
        header: HeaderMap,
        uri: Uri,
        Extension(app_dbs): Extension<Arc<AppDBs>>,
        Extension(cookies): Extension<Cookies>,
        Extension(random): Extension<Random>,
        ConnectInfo(app_connect_info): ConnectInfo<AppConnectInfo>,
        Json(user_item): Json<UserItem>,
    ) -> Response {
        let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
        let req_handler = ReqHandler::new(
            ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string()), &app_connect_info),
            &app_dbs,
            &uri,
            &auth_state,
            &random,
            "log_delete_handler"
        ); 
        if auth_state.session.is_none() {
            let _ = req_handler.trace_req(format!("No session found"));
            return (
               StatusCode::UNAUTHORIZED,
               req_handler.req_header.header,
               "Error"
           ).into_response();
        }
        let mut res_headers = HeaderMap::new();
        res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
        let user_id = auth_state.user_id();
        if user_id.is_empty() {
            let _ = req_handler.trace_req(format!("No user found"));
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        if ! is_allowed(&auth_state,&app_dbs.config.auth_roles,&req_handler) {
            return (
                StatusCode::UNAUTHORIZED,
                res_headers,
                "Error"
           ).into_response();
        }
        let trace_data = TraceData { user_id: user_item.name.to_owned(), timestamp: String::from(""), contents: Vec::new() };
        match trace_data.clean(&app_dbs.config, &user_item.value) {
            Ok(_) => {
                // Turn off logging this here !!!
                // let _ = req_handler.trace_req(format!("Log '{}' = '{}' deleted",&user_item.name, &user_item.value));
                (
                    res_headers,
                    "OK".to_owned()
                ).into_response()
            },
            Err(e) => {
                let msg = format!("Log '{}' = '{}' not deleted",&user_item.name, &user_item.value);
                let _ = req_handler.trace_req(format!("{}", &msg));
                println!("Error {}: {}", &msg,e);
                (
                   StatusCode::BAD_REQUEST,
                        res_headers,
                        "Error"
                ).into_response()
            }
        }
    }
    route("/users", get(users_handler))
        .route("/userget", post(user_get_handler))
        .route("/usersave", post(user_save_handler))
        .route("/userdelete", post(user_delete_handler))
        .route("/userdisabletotp", post(user_disable_totp_handler))
        .route("/userasadmin", post(user_as_admin_handler))
        .route("/passwdreset", post(user_passwd_reset_handler))
        .route("/logs", get(logs_handler))
        .route("/log/:id", get(log_id_handler))
        .route("/logdelete", post(log_delete_handler))
}