use crate::api::auth::Session;
use crate::error::ApiResult;
use crate::svc::user_svc::UserService;
use chrono::{DateTime, Utc};
use rocket::serde::{Deserialize, Serialize};
use rocket::State;
use sqlx::FromRow;
use crate::api::totp::TotpStatus;

#[derive(Clone)]
#[derive(FromRow)]
pub struct User {
    pub id: i64,
    pub email: Option<String>,
    pub username: String,
    pub nickname: Option<String>,
    pub passhash: String,
    pub totp_status: TotpStatus,
    pub totp_secret: Option<String>,
    pub created_at: Option<DateTime<Utc>>,
    pub updated_at: Option<DateTime<Utc>>,
}

#[derive(Debug, sqlx::Type, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
#[sqlx(type_name = "user_role", rename_all = "lowercase")]
pub enum UserRole {
    User,
    Admin,
}

// pub struct UserCache {}
//
// impl UserCache {
//     pub async fn username(
//         id: usize,
//         redis_conn: &mut Connection<Redis>,
//         pgsql_conn: &mut Connection<Postgres>,
//     ) -> String {
//         if let Ok(val) = redis_conn.get(format!("users:{id}")).await {
//             return val;
//         }
//
//         if let Ok(v) = sqlx::query!("SELECT username FROM users WHERE id = $1", id as i32)
//             .fetch_one(&mut ***pgsql_conn)
//             .await
//         {
//             let username = v.username;
//             Self::insert(id, &username, redis_conn).await;
//             username
//         } else {
//             unimplemented!()
//         }
//     }
//
//     pub async fn insert(id: usize, username: &str, conn: &mut Connection<Redis>) {
//         conn.set_ex::<_, _, ()>(format!("users:{id}"), username.to_string(), 1800)
//             .await
//             .expect("failed to insert key");
//     }
// }
