use serde::Serialize;
use sqlx::{FromRow, SqlitePool};

#[derive(FromRow, Serialize, Clone)]
pub struct Role {
    pub(crate) id: i64,
    pub(crate) name: String,
}

impl Role {
    pub async fn all(db: &SqlitePool) -> Vec<Role> {
        sqlx::query_as!(Role, "SELECT id, name FROM role")
            .fetch_all(db)
            .await
            .unwrap()
    }

    pub async fn find_by_id(db: &SqlitePool, name: i32) -> Option<Self> {
        sqlx::query_as!(
            Self,
            "
SELECT id, name
FROM role 
WHERE id like ?
        ",
            name
        )
        .fetch_one(db)
        .await
        .ok()
    }

    pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> {
        sqlx::query_as!(
            Self,
            "
SELECT id, name
FROM role 
WHERE name like ?
        ",
            name
        )
        .fetch_one(db)
        .await
        .ok()
    }

    pub async fn names_from_role(&self, db: &SqlitePool) -> Vec<String> {
        let query = format!(
            "SELECT u.name
         FROM user u
         JOIN user_role ur ON u.id = ur.user_id
         JOIN role r ON ur.role_id = r.id
         WHERE r.id = {} AND deleted=0;",
            self.id
        );

        sqlx::query_scalar(&query).fetch_all(db).await.unwrap()
    }

    pub async fn mails_from_role(&self, db: &SqlitePool) -> Vec<String> {
        let query = format!(
            "SELECT u.mail
         FROM user u
         JOIN user_role ur ON u.id = ur.user_id
         JOIN role r ON ur.role_id = r.id
         WHERE r.id = {} AND deleted=0;",
            self.id
        );

        sqlx::query_scalar(&query).fetch_all(db).await.unwrap()
    }
}
