use common_contracts::dtos::ProviderCacheDto;
use sqlx::PgPool;
use chrono::Utc;

pub async fn get_cache(
    pool: &PgPool,
    key: &str,
) -> Result<Option<ProviderCacheDto>, sqlx::Error> {
    let now = Utc::now();
    
    // We also check expiration here for safety, 
    // though the caller might want to know if it exists but is expired.
    // For now, we treat expired as not found.
    let record = sqlx::query_as!(
        ProviderCacheDto,
        r#"
        SELECT 
            cache_key, 
            data_payload, 
            updated_at, 
            expires_at
        FROM provider_response_cache
        WHERE cache_key = $1 AND expires_at > $2
        "#,
        key,
        now
    )
    .fetch_optional(pool)
    .await?;

    Ok(record)
}

pub async fn set_cache(
    pool: &PgPool,
    dto: &ProviderCacheDto,
) -> Result<(), sqlx::Error> {
    sqlx::query(
        r#"
        INSERT INTO provider_response_cache (cache_key, data_payload, expires_at)
        VALUES ($1, $2, $3)
        ON CONFLICT (cache_key) DO UPDATE SET
            data_payload = EXCLUDED.data_payload,
            expires_at = EXCLUDED.expires_at,
            updated_at = NOW()
        "#,
    )
    .bind(&dto.cache_key)
    .bind(&dto.data_payload)
    .bind(dto.expires_at)
    .execute(pool)
    .await?;

    Ok(())
}

