//! Error types - re-exported from shared-api-lib with project-specific conversions
//!
//! For full documentation, see shared_api_lib::error

use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};
use serde_json::json;
use thiserror::Error;

/// Project-lifecycle API error type
///
/// Mirrors the shared ApiError but adds support for project-specific error types
#[derive(Debug, Error)]
pub enum ApiError {
    /// Not found
    #[error("Not found: {0}")]
    NotFound(String),

    /// Validation error
    #[allow(dead_code)]
    #[error("Validation error: {0}")]
    Validation(String),

    /// Internal server error
    #[allow(dead_code)]
    #[error("Internal server error: {0}")]
    Internal(String),

    /// Conflict
    #[allow(dead_code)]
    #[error("Conflict: {0}")]
    Conflict(String),

    /// Unauthorized
    #[error("Unauthorized: {0}")]
    Unauthorized(String),

    /// Bad request
    #[error("Bad request: {0}")]
    BadRequest(String),

    /// Database error
    #[error("Database error: {0}")]
    Database(String),
}

impl IntoResponse for ApiError {
    fn into_response(self) -> Response {
        let (status, error_message) = match self {
            ApiError::NotFound(ref msg) => (StatusCode::NOT_FOUND, msg.clone()),
            ApiError::Validation(ref msg) | ApiError::BadRequest(ref msg) => {
                (StatusCode::BAD_REQUEST, msg.clone())
            }
            ApiError::Conflict(ref msg) => (StatusCode::CONFLICT, msg.clone()),
            ApiError::Unauthorized(ref msg) => (StatusCode::UNAUTHORIZED, msg.clone()),
            ApiError::Database(_) | ApiError::Internal(_) => (
                StatusCode::INTERNAL_SERVER_ERROR,
                "Internal server error".to_string(),
            ),
        };

        let body = Json(json!({
            "error": error_message,
            "status": status.as_u16(),
        }));

        (status, body).into_response()
    }
}

/// Result type for API operations
pub type ApiResult<T> = Result<T, ApiError>;

/// Convert syntaxis_core errors to API errors
impl From<syntaxis_core::error::LifecycleError> for ApiError {
    fn from(err: syntaxis_core::error::LifecycleError) -> Self {
        ApiError::Database(err.to_string())
    }
}

/// Convert sqlx errors to API errors
impl From<sqlx::Error> for ApiError {
    fn from(err: sqlx::Error) -> Self {
        ApiError::Database(format!("Database error: {}", err))
    }
}

/// Convert anyhow errors to API errors
impl From<anyhow::Error> for ApiError {
    fn from(err: anyhow::Error) -> Self {
        ApiError::Internal(err.to_string())
    }
}
