pub mod common;
pub mod item;
pub mod status;

use axum::{
    Router,
    routing::{delete, get, post},
};

use crate::modes::server::common::AppState;
use utoipa::OpenApi;

#[cfg(feature = "swagger")]
use utoipa_swagger_ui::SwaggerUi;

#[derive(OpenApi)]
#[openapi(
    info(
        title = "Keep API",
        version = "0.1.0",
        description = "REST API for Keep - a tool to manage temporary files with automatic compression and metadata generation",
        contact(
            name = "Keep Project",
        )
    ),
    paths(
        status::handle_status,
        item::handle_list_items,
        item::handle_post_item,
        item::handle_get_item_latest_meta,
        item::handle_get_item_latest_content,
        item::handle_get_item_meta,
        item::handle_get_item_content,
    ),
    components(
        schemas(
            crate::modes::server::common::ItemInfo,
            crate::modes::server::common::ItemContentInfo,
            crate::modes::server::common::ItemInfoListResponse,
            crate::modes::server::common::ItemInfoResponse,
            crate::modes::server::common::ItemContentInfoResponse,
            crate::modes::server::common::MetadataResponse,
            crate::modes::server::common::StatusInfoResponse,
            crate::common::status::StatusInfo,
            crate::modes::server::common::ItemQuery,
            crate::modes::server::common::ItemContentQuery,
        )
    ),
    tags(
        (name = "status", description = "System status and health check endpoints"),
        (name = "item", description = "Item management endpoints for storing, retrieving, and managing content with metadata"),
    ),
    servers(
        (url = "/", description = "Local server")
    )
)]
#[allow(dead_code)]
struct ApiDoc;

pub fn add_routes(router: Router<AppState>) -> Router<AppState> {
    router
        // Status endpoints
        .route("/api/status", get(status::handle_status))
        .route("/api/plugins/status", get(status::handle_plugins_status))
        // Item endpoints
        .route(
            "/api/item/",
            get(item::handle_list_items).post(item::handle_post_item),
        )
        .route(
            "/api/item/latest/meta",
            get(item::handle_get_item_latest_meta),
        )
        .route(
            "/api/item/latest/content",
            get(item::handle_get_item_latest_content),
        )
        .route(
            "/api/item/{item_id}/meta",
            get(item::handle_get_item_meta).post(item::handle_post_item_meta),
        )
        .route(
            "/api/item/{item_id}/content",
            get(item::handle_get_item_content),
        )
        .route("/api/item/{item_id}", delete(item::handle_delete_item))
        .route("/api/item/{item_id}/info", get(item::handle_get_item_info))
        .route("/api/item/{item_id}/update", post(item::handle_update_item))
        .route("/api/diff", get(item::handle_diff_items))
}

#[cfg(feature = "swagger")]
pub fn add_docs_routes(router: Router<AppState>) -> Router<AppState> {
    router.merge(SwaggerUi::new("/swagger").url("/openapi.json", ApiDoc::openapi()))
}

#[cfg(not(feature = "swagger"))]
pub fn add_docs_routes(router: Router<AppState>) -> Router<AppState> {
    router
}
