use crate::error::{ApiError, ok_json};
use actix_web::{HttpResponse, web};
use serde::Deserialize;
use service::AppService;
use service::Pagination;
use service::ai::types::{
    AiDiscussionResponse, AiLikeResponse, AiModelCardResponse, AiModelFilter,
    AiModelListItem, AiModelResponse, AiModelVersionResponse,
};
use session::Session;
use uuid::Uuid;

#[derive(Deserialize, utoipa::IntoParams)]
pub struct ModelIdPath {
    pub id: Uuid,
}
#[utoipa::path(
    get, path = "/api/v1/ai/models",
    params(AiModelFilter, Pagination),
    responses((status = 200, body = Vec<AiModelListItem>), (status = 401, description = "Unauthorized")),
    security(("session" = []))
)]
pub async fn list_models(
    session: Session,
    service: web::Data<AppService>,
    filter: web::Query<AiModelFilter>,
    pagination: web::Query<Pagination>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_list(
                &session,
                filter.into_inner(),
                pagination.into_inner(),
            )
            .await?,
    )
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}",
    params(("id" = String, Path)), responses((status = 200, body = AiModelResponse),
        (status = 401, description = "Unauthorized"), (status = 404, description = "Not found")),
    security(("session" = []))
)]
pub async fn get_model(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
) -> Result<HttpResponse, ApiError> {
    ok_json(service.ai_model_get(&session, path.into_inner().id).await?)
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}/versions",
    params(("id" = String, Path)), responses((status = 200, body = Vec<AiModelVersionResponse>),
        (status = 401, description = "Unauthorized")),
    security(("session" = []))
)]
pub async fn list_versions(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_versions(&session, path.into_inner().id)
            .await?,
    )
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}/card",
    params(("id" = String, Path)), responses((status = 200, body = Option<AiModelCardResponse>),
        (status = 401, description = "Unauthorized")),
    security(("session" = []))
)]
pub async fn get_card(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_card(&session, path.into_inner().id)
            .await?,
    )
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}/tags",
    params(("id" = String, Path)), responses((status = 200, body = Vec<String>)),
    security(("session" = []))
)]
pub async fn list_tags(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_tags(&session, path.into_inner().id)
            .await?,
    )
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}/discussions",
    params(("id" = String, Path), Pagination),
    responses((status = 200, body = Vec<AiDiscussionResponse>)),
    security(("session" = []))
)]
pub async fn list_discussions(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
    pagination: web::Query<Pagination>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_discussions(
                &session,
                path.into_inner().id,
                pagination.into_inner(),
            )
            .await?,
    )
}
#[utoipa::path(
    get, path = "/api/v1/ai/models/{id}/likes",
    params(("id" = String, Path)), responses((status = 200, body = Vec<AiLikeResponse>)),
    security(("session" = []))
)]
pub async fn list_likes(
    session: Session,
    service: web::Data<AppService>,
    path: web::Path<ModelIdPath>,
) -> Result<HttpResponse, ApiError> {
    ok_json(
        service
            .ai_model_likes(&session, path.into_inner().id)
            .await?,
    )
}
