use async_graphql::{Context, Object, Result};
use uuid::Uuid;

use crate::db::Database;
use crate::graphql::types::ProjectScopeTemplateType;
use crate::models::ProjectScopeTemplate;

#[derive(Default)]
pub struct ProjectScopeTemplateQuery;

#[Object]
impl ProjectScopeTemplateQuery {
    /// Get all project scope templates
    async fn project_scope_templates(
        &self,
        ctx: &Context<'_>,
        #[graphql(desc = "Filter by active status")] is_active: Option<bool>,
    ) -> Result<Vec<ProjectScopeTemplateType>> {
        let db = ctx.data::<Database>()?;
        let pool = db.pool().await;

        let templates: Vec<ProjectScopeTemplate> = sqlx::query_as::<_, ProjectScopeTemplate>(
            r#"
            SELECT id, created_at, updated_at, name, description, is_active
            FROM project_scope_templates
            WHERE ($1::boolean IS NULL OR is_active = $1)
            ORDER BY name ASC
            "#,
        )
        .bind(is_active)
        .fetch_all(&*pool)
        .await?;

        Ok(templates
            .into_iter()
            .map(ProjectScopeTemplateType::from)
            .collect())
    }

    /// Get a single project scope template by ID
    async fn project_scope_template(&self, ctx: &Context<'_>, id: Uuid) -> Result<Option<ProjectScopeTemplateType>> {
        let db = ctx.data::<Database>()?;
        let pool = db.pool().await;

        let template = sqlx::query_as::<_, ProjectScopeTemplate>(
            r#"
            SELECT id, created_at, updated_at, name, description, is_active
            FROM project_scope_templates
            WHERE id = $1
            "#,
        )
        .bind(id)
        .fetch_one(&*pool)
        .await
        .ok();

        Ok(template.map(ProjectScopeTemplateType::from))
    }
}
