use crate::{datasources::posts::PostsDatasource, AppState};
use axum::{
    extract::State,
    http::StatusCode,
    response::{IntoResponse, Response},
    routing::get,
    Json, Router,
};
use chrono::Utc;
use serde::{Serialize, Serializer};
use sqlx::{PgPool, Pool, Postgres};

#[derive(sqlx::FromRow, Serialize)]
pub struct Post {
    pub post_id: i32,
    pub title: String,
    pub body: String,
    #[serde(serialize_with = "serialize_datetime")]
    pub created_at: chrono::DateTime<Utc>,
}

pub struct PostsRoute;
impl PostsRoute {
    pub fn routes(app_state: &AppState) -> Router {
        // add more post routes here!
        Router::new()
            .route("/all", get(PostsRoute::get_all))
            // .route("/:id", get(PostsRoute::get_one))
            .with_state(app_state.db.clone())
    }

    // get all posts
    async fn get_all(State(pool): State<Pool<Postgres>>) -> impl IntoResponse {
        match PostsDatasource::get_all(&pool).await {
            Ok(posts) => Ok(Json(posts)),
            Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
        }
    }

    // get one post
    // async fn get_one(State(pool): State<PgPool>) -> Json<()> {
    //     let results = PostsDatasource::get_one(pool).await;
    //     Json {}
    // }

    // get the top three posts with the highest view count
    // async fn get_popular_posts(State(pool): State<PgPool>) {}

    // get the top three posts with the most comments
    // async fn get_hot_posts(State(pool): State<PgPool>) {}
}

fn serialize_datetime<S>(date: &chrono::DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_str(&date.to_rfc3339())
}