use diesel::{
    dsl::{auto_type, AsSelect, Eq},
    pg::Pg,
    prelude::*,
};
use uuid::Uuid;

use crate::{
    channels::Channel,
    schema::{channel_selections, channels, email_channels, projects, slack_channels},
    teams::Team,
};

#[derive(Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable)]
#[diesel(table_name = projects)]
#[diesel(belongs_to(Team))]
pub struct Project {
    pub id: Uuid,
    pub team_id: Uuid,
    pub name: String,
}

impl Project {
    #[auto_type(no_type_alias)]
    pub fn all() -> _ {
        let select: AsSelect<Project, Pg> = Project::as_select();
        projects::table.select(select)
    }

    #[auto_type(no_type_alias)]
    pub fn with_id(project_id: Uuid) -> _ {
        projects::id.eq(project_id)
    }

    #[auto_type(no_type_alias)]
    pub fn with_team(team_id: Uuid) -> _ {
        projects::team_id.eq(team_id)
    }

    #[auto_type(no_type_alias)]
    pub fn with_name(name: String) -> _ {
        projects::name.eq(name)
    }

    #[auto_type(no_type_alias)]
    pub fn selected_channels(&self) -> _ {
        let select: AsSelect<Channel, Pg> = Channel::as_select();
        let project_filter: Eq<channel_selections::project_id, Uuid> =
            channel_selections::project_id.eq(self.id);
        channels::table
            .left_join(email_channels::table)
            .left_join(slack_channels::table)
            .inner_join(channel_selections::table)
            .filter(project_filter)
            .select(select)
    }
}
