//! {{RESOURCE_NAME}} controller
//!
//! Generated by: keg gen api {{RESOURCE_NAME}}
//!
//! Controller layer: receives HTTP requests, calls the service layer,
//! and returns JSON responses.

use crate::error::{AppError, AppResult};
use crate::internal::service::{{RESOURCE_NAME}}_service::{{RESOURCE_NAME_PASCAL}}Service;
use actix_web::{web, HttpResponse};
use serde::{{Deserialize, Serialize}};
use uuid::Uuid;

// ── Request DTOs ──────────────────────────────────────────────────────────────

#[derive(Debug, Deserialize)]
pub struct Create{{RESOURCE_NAME_PASCAL}}Request {
    pub name: String,
}

#[derive(Debug, Deserialize)]
pub struct Update{{RESOURCE_NAME_PASCAL}}Request {
    pub name: Option<String>,
}

// ── Response DTOs ─────────────────────────────────────────────────────────────

#[derive(Debug, Serialize)]
pub struct {{RESOURCE_NAME_PASCAL}}Response {
    pub id: Uuid,
    pub name: String,
    pub created_at: chrono::DateTime<chrono::Utc>,
    pub updated_at: chrono::DateTime<chrono::Utc>,
}

// ── Controller ─────────────────────────────────────────────────────────────────

/// GET /api/v1/{{RESOURCE_NAME}}
pub async fn list() -> AppResult<Json<Vec<{{RESOURCE_NAME_PASCAL}}Response>>> {
    let items = {{RESOURCE_NAME_PASCAL}}Service::list().await?;
    Ok(Json(items))
}

/// GET /api/v1/{{RESOURCE_NAME}}/{id}
pub async fn get(web::Path(id): web::Path<Uuid>) -> AppResult<Json<{{RESOURCE_NAME_PASCAL}}Response>> {
    match {{RESOURCE_NAME_PASCAL}}Service::get(id).await? {
        Some(item) => Ok(Json(item)),
        None => Err(AppError::not_found("{{RESOURCE_NAME}} not found")),
    }
}

/// POST /api/v1/{{RESOURCE_NAME}}
pub async fn create(
    body: web::Json<Create{{RESOURCE_NAME_PASCAL}}Request>,
) -> AppResult<HttpResponse> {
    let item = {{RESOURCE_NAME_PASCAL}}Service::create(&body.name).await?;
    Ok(HttpResponse::Created().json(item))
}

/// PUT /api/v1/{{RESOURCE_NAME}}/{id}
pub async fn update(
    path: web::Path<Uuid>,
    body: web::Json<Update{{RESOURCE_NAME_PASCAL}}Request>,
) -> AppResult<Json<{{RESOURCE_NAME_PASCAL}}Response>> {
    let id = path.into_inner();
    let item = {{RESOURCE_NAME_PASCAL}}Service::update(id, body.name.as_deref()).await?;
    Ok(Json(item))
}

/// DELETE /api/v1/{{RESOURCE_NAME}}/{id}
pub async fn delete(path: web::Path<Uuid>) -> AppResult<HttpResponse> {
    let id = path.into_inner();
    {{RESOURCE_NAME_PASCAL}}Service::delete(id).await?;
    Ok(HttpResponse::NoContent().finish())
}