use anyhow::{Result, Context};
use sqlx::PgPool;
use uuid::Uuid;

/// {{SERVICE_NAME}}Service provides business logic for {{DOMAIN}}
pub struct {{SERVICE_NAME}}Service {
    pool: PgPool,
}

impl {{SERVICE_NAME}}Service {
    /// Creates a new {{SERVICE_NAME}}Service instance
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }

    /// Creates a new {{ENTITY}}
    pub async fn create_{{ENTITY_LOWER}}(
        &self,
        request: Create{{ENTITY}}Request,
    ) -> Result<{{ENTITY}}> {
        // Validation
        request.validate()?;

        // Business logic
        let {{ENTITY_LOWER}} = sqlx::query_as!(
            {{ENTITY}},
            r#"
            INSERT INTO {{TABLE_NAME}} (id, /* TODO: add fields */)
            VALUES ($1, /* TODO: add values */)
            RETURNING id, /* TODO: add fields */
            "#,
            Uuid::new_v4(),
            // TODO: add request fields
        )
        .fetch_one(&self.pool)
        .await
        .context("Failed to create {{ENTITY_LOWER}}")?;

        Ok({{ENTITY_LOWER}})
    }

    /// Gets a {{ENTITY}} by ID
    pub async fn get_{{ENTITY_LOWER}}_by_id(
        &self,
        id: Uuid,
    ) -> Result<{{ENTITY}}> {
        let {{ENTITY_LOWER}} = sqlx::query_as!(
            {{ENTITY}},
            r#"
            SELECT id, /* TODO: add fields */
            FROM {{TABLE_NAME}}
            WHERE id = $1
            "#,
            id
        )
        .fetch_optional(&self.pool)
        .await
        .context("Failed to fetch {{ENTITY_LOWER}}")?
        .ok_or_else(|| anyhow::anyhow!("{{ENTITY}} not found"))?;

        Ok({{ENTITY_LOWER}})
    }
}

/// Request to create a {{ENTITY}}
#[derive(Debug)]
pub struct Create{{ENTITY}}Request {
    // TODO: Add request fields
}

impl Create{{ENTITY}}Request {
    /// Validates the request
    pub fn validate(&self) -> Result<()> {
        // TODO: Add validation logic
        Ok(())
    }
}

/// {{ENTITY}} model
#[derive(Debug)]
pub struct {{ENTITY}} {
    pub id: Uuid,
    // TODO: Add entity fields
}







