Skip to content
use crate::auth::Goal;
use crate::db::Database;

impl Database {
    pub async fn create_goal(&self, goal: &Goal) -> Result<(), String> {
        self.conn()
            .await?
            .execute(
                "INSERT INTO goals (id, name, target_points, created_at) VALUES (?1, ?2, ?3, ?4)",
                turso::params![
                    goal.id.clone(),
                    goal.name.clone(),
                    goal.target_points,
                    goal.created_at.clone()
                ],
            )
            .await
            .map_err(|e| e.to_string())?;
        Ok(())
    }

    pub async fn get_active_goal(&self) -> Result<Option<Goal>, String> {
        let mut rows = self
            .conn()
            .await?
            .query(
                "SELECT id, name, target_points, created_at FROM goals ORDER BY created_at DESC LIMIT 1",
                (),
            )
            .await
            .map_err(|e| e.to_string())?;

        if let Some(row) = rows.next().await.map_err(|e| e.to_string())? {
            Ok(Some(Goal {
                id: row.get(0).map_err(|e| e.to_string())?,
                name: row.get(1).map_err(|e| e.to_string())?,
                target_points: row.get(2).map_err(|e| e.to_string())?,
                created_at: row.get(3).map_err(|e| e.to_string())?,
            }))
        } else {
            Ok(None)
        }
    }

    pub async fn delete_goal(&self, id: &str) -> Result<(), String> {
        self.conn()
            .await?
            .execute("DELETE FROM goals WHERE id = ?1", turso::params![id])
            .await
            .map_err(|e| e.to_string())?;
        Ok(())
    }

    pub async fn update_goal_target_points(
        &self,
        id: &str,
        target_points: f64,
    ) -> Result<(), String> {
        self.conn()
            .await?
            .execute(
                "UPDATE goals SET target_points = ?1 WHERE id = ?2",
                turso::params![target_points, id],
            )
            .await
            .map_err(|e| e.to_string())?;
        Ok(())
    }

    pub async fn get_total_points(&self) -> Result<f64, String> {
        let mut rows = self
            .conn()
            .await?
            .query(
                "SELECT COALESCE(SUM(points_earned), 0.0) FROM exercise_logs",
                (),
            )
            .await
            .map_err(|e| e.to_string())?;

        if let Some(row) = rows.next().await.map_err(|e| e.to_string())? {
            Ok(row.get(0).map_err(|e| e.to_string())?)
        } else {
            Ok(0.0)
        }
    }
}