use axum::{
    extract::{Path, Query, State},
    Json,
};
use uuid::Uuid;

use crate::{
    error::Result,
    models::{Bulletin, CreateBulletinRequest, ApiResponse, PaginatedResponse},
    utils::{
        common::ListQueryParams,
        response::{success_response, success_with_message},
        urls::UrlBuilder,
        pagination::PaginationHelper,
    },
    services::BulletinService,
    AppState,
};

// Use shared ListQueryParams instead of custom ListQuery
// #[derive(Deserialize)]
// pub struct ListQuery {
//     page: Option<i32>,
//     per_page: Option<i32>,
//     active_only: Option<bool>,
// }

pub async fn list(
    State(state): State<AppState>,
    Query(query): Query<ListQueryParams>,
) -> Result<Json<ApiResponse<PaginatedResponse<Bulletin>>>> {
    let pagination = PaginationHelper::from_query(query.page, query.per_page);
    let url_builder = UrlBuilder::new();
    
    let (bulletins, total) = BulletinService::list_v1(
        &state.pool,
        pagination.page,
        pagination.per_page as i64,
        query.active_only.unwrap_or(false),
        &url_builder,
    ).await?;
    
    let response = pagination.create_response(bulletins, total);
    Ok(success_response(response))
}

pub async fn current(
    State(state): State<AppState>,
) -> Result<Json<ApiResponse<Option<Bulletin>>>> {
    let url_builder = UrlBuilder::new();
    let bulletin = BulletinService::get_current_v1(&state.pool, &url_builder).await?;
    
    Ok(success_response(bulletin))
}

pub async fn next(
    State(state): State<AppState>,
) -> Result<Json<ApiResponse<Option<Bulletin>>>> {
    let url_builder = UrlBuilder::new();
    let bulletin = BulletinService::get_next_v1(&state.pool, &url_builder).await?;
    
    Ok(success_response(bulletin))
}

pub async fn get(
    State(state): State<AppState>,
    Path(id): Path<Uuid>,
) -> Result<Json<ApiResponse<Bulletin>>> {
    let url_builder = UrlBuilder::new();
    let bulletin = BulletinService::get_by_id_v1(&state.pool, &id, &url_builder).await?
        .ok_or_else(|| crate::error::ApiError::NotFound("Bulletin not found".to_string()))?;
    
    Ok(success_response(bulletin))
}

pub async fn create(
    State(state): State<AppState>,
    Json(req): Json<CreateBulletinRequest>,
) -> Result<Json<ApiResponse<Bulletin>>> {
    let url_builder = UrlBuilder::new();
    let bulletin = BulletinService::create(&state.pool, req, &url_builder).await?;
    
    Ok(success_response(bulletin))
}

pub async fn update(
    State(state): State<AppState>,
    Path(id): Path<Uuid>,
    Json(req): Json<CreateBulletinRequest>,
) -> Result<Json<ApiResponse<Bulletin>>> {
    let url_builder = UrlBuilder::new();
    let bulletin = BulletinService::update(&state.pool, &id, req, &url_builder).await?
        .ok_or_else(|| crate::error::ApiError::NotFound("Bulletin not found".to_string()))?;
    
    Ok(success_with_message(bulletin, "Bulletin updated successfully"))
}

pub async fn delete(
    State(state): State<AppState>,
    Path(id): Path<Uuid>,
) -> Result<Json<ApiResponse<()>>> {
    BulletinService::delete(&state.pool, &id).await?;
    
    Ok(Json(ApiResponse {
        success: true,
        data: Some(()),
        message: Some("Bulletin deleted successfully".to_string()),
    }))
}


