//! Media proxy route for authenticated S3 access
//!
//! Proxies requests to S3/Garage with authentication, allowing
//! session media to be accessed only by authenticated users.

use std::sync::Arc;

use axum::{
    body::Body,
    extract::{Path, State},
    http::{header, Response, StatusCode},
    response::IntoResponse,
};

use crate::services::S3Service;

/// Shared state for media routes
#[derive(Clone)]
pub struct MediaState {
    pub s3: Arc<S3Service>,
}

/// Proxy a file from S3
///
/// GET /api/media/{path}
///
/// This endpoint requires authentication (handled by middleware).
/// It fetches the file from S3 and streams it to the client.
pub async fn get_media(
    State(state): State<MediaState>,
    Path(path): Path<String>,
) -> impl IntoResponse {
    match state.s3.get_file(&path).await {
        Ok((data, content_type)) => {
            // Build response with proper headers
            Response::builder()
                .status(StatusCode::OK)
                .header(header::CONTENT_TYPE, content_type)
                .header(header::CONTENT_LENGTH, data.len())
                .header(header::CACHE_CONTROL, "private, max-age=86400") // Cache for 1 day
                .body(Body::from(data))
                .unwrap()
        }
        Err(e) => {
            tracing::warn!(path = %path, error = %e, "Failed to fetch media from S3");
            Response::builder()
                .status(StatusCode::NOT_FOUND)
                .header(header::CONTENT_TYPE, "application/json")
                .body(Body::from(r#"{"error": "Media not found"}"#))
                .unwrap()
        }
    }
}

/// Check if a file exists in S3 (HEAD request)
pub async fn head_media(
    State(state): State<MediaState>,
    Path(path): Path<String>,
) -> impl IntoResponse {
    if state.s3.file_exists(&path).await {
        StatusCode::OK
    } else {
        StatusCode::NOT_FOUND
    }
}
