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

use crate::db::Database;
use crate::graphql::types::ServiceScopeTemplateType;
use crate::models::ServiceScopeTemplate;

#[derive(Default)]
pub struct ServiceScopeTemplateQuery;

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

        let templates: Vec<ServiceScopeTemplate> = sqlx::query_as::<_, ServiceScopeTemplate>(
            r#"
            SELECT id, created_at, updated_at, name, description, is_active
            FROM service_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(ServiceScopeTemplateType::from)
            .collect())
    }

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

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

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