use axum::{
    extract::{FromRef, FromRequestParts},
    http::request::Parts,
};
use deadpool_diesel::postgres::{Connection, Pool};
use oauth2::basic::BasicClient;

use crate::{app_error::AppError, sessions::PgStore, settings::Settings};

#[derive(Clone)]
pub(crate) struct AppState {
    pub db_pool: Pool,
    pub oauth_client: BasicClient,
    pub session_store: PgStore,
    pub settings: Settings,
}

impl FromRef<AppState> for PgStore {
    fn from_ref(state: &AppState) -> Self {
        state.session_store.clone()
    }
}

pub struct DbConn(pub Connection);

impl FromRequestParts<AppState> for DbConn {
    type Rejection = AppError;

    async fn from_request_parts(_: &mut Parts, state: &AppState) -> Result<Self, Self::Rejection> {
        let conn = state.db_pool.get().await?;
        Ok(Self(conn))
    }
}
