Skip to main content

game_manager_lib/services/integration/
gamerpower.rs

1//! Integração com GamerPower API para buscar jogos grátis.
2//!
3//! Fornece funcionalidades para obter ofertas ativas de jogos gratuitos para PC.
4//! A GamerPower é uma plataforma que agrega ofertas de jogos gratuitos de várias fontes.
5
6use crate::constants::{GAMERPOWER_CACHE_SOURCE, GAMERPOWER_LIST_ACTIVE_CACHE_KEY};
7use crate::database::AppState;
8use crate::services::cache;
9use crate::utils::http_client::HTTP_CLIENT;
10use serde::{Deserialize, Serialize};
11use tauri::{AppHandle, Manager};
12
13#[derive(Debug, Serialize, Deserialize, Clone)]
14pub struct Giveaway {
15    pub id: u32,
16    pub title: String,
17    pub worth: String,     // ex: "$29.99" or "N/A"
18    pub thumbnail: String, // Imagem pequena
19    pub image: String,     // Imagem grande (Landscape) - Usaremos essa no card estilo Epic
20    pub description: String,
21    pub instructions: String,
22    #[serde(rename = "open_giveaway_url")]
23    pub open_giveaway_url: String,
24    #[serde(rename = "published_date")]
25    pub published_date: String,
26    #[serde(rename = "type")]
27    pub type_prop: String, // "Game", "DLC"
28    pub platforms: String, // "PC, Steam, Epic Games Store"
29    #[serde(rename = "end_date")]
30    pub end_date: Option<String>,
31    pub status: String, // "Active"
32}
33
34/// Busca ofertas ativas para PC
35pub async fn fetch_giveaways(app: &AppHandle) -> Result<Vec<Giveaway>, String> {
36    let cache_key = GAMERPOWER_LIST_ACTIVE_CACHE_KEY;
37    let url = "https://www.gamerpower.com/api/giveaways?platform=pc&type=game&sort-by=popularity";
38
39    // 1. Tenta reaproveitar cache válido antes de consultar a API
40    if let Ok(conn) = app.state::<AppState>().cache_db.lock() {
41        if let Some(payload) = cache::get_cached_api_data(&conn, GAMERPOWER_CACHE_SOURCE, cache_key)
42        {
43            if let Ok(cached_giveaways) = serde_json::from_str::<Vec<Giveaway>>(&payload) {
44                return Ok(cached_giveaways);
45            }
46        }
47    }
48
49    // 2. Tenta buscar ONLINE
50    if let Ok(res) = HTTP_CLIENT.get(url).send().await {
51        if res.status().is_success() {
52            let giveaways: Vec<Giveaway> = res.json().await.map_err(|e| e.to_string())?;
53
54            // Filtra apenas ativos
55            let active_ones: Vec<Giveaway> = giveaways
56                .into_iter()
57                .filter(|g| g.status == "Active")
58                .collect();
59
60            // Sucesso: Salva a lista filtrada no Cache
61            if let Ok(conn) = app.state::<AppState>().cache_db.lock() {
62                if let Ok(json) = serde_json::to_string(&active_ones) {
63                    let _ = cache::save_cached_api_data(
64                        &conn,
65                        GAMERPOWER_CACHE_SOURCE,
66                        cache_key,
67                        &json,
68                    );
69                }
70            }
71
72            return Ok(active_ones);
73        }
74    }
75
76    Err("Não foi possível carregar jogos grátis (sem conexão e sem cache).".to_string())
77}