use sqlx::{query, PgPool};

use super::Result;

pub struct Vehicle {
    pub id: i32,
    pub radio_call_name: String,
    pub station: String,
}

impl Vehicle {
    pub async fn create(pool: &PgPool, radio_call_name: &str, station: &str) -> Result<()> {
        query!(
            "INSERT INTO vehicle (radioCallName, station) VALUES ($1, $2);",
            radio_call_name,
            station
        )
        .execute(pool)
        .await?;

        Ok(())
    }

    pub async fn read_all(pool: &PgPool) -> Result<Vec<Vehicle>> {
        let records = query!("SELECT * FROM vehicle;").fetch_all(pool).await?;

        let vehicles = records
            .into_iter()
            .map(|v| Vehicle {
                id: v.id,
                radio_call_name: v.radiocallname,
                station: v.station,
            })
            .collect();

        Ok(vehicles)
    }

    pub async fn read(pool: &PgPool, id: i32) -> Result<Option<Vehicle>> {
        let record = query!("SELECT * FROM vehicle WHERE id = $1;", id)
            .fetch_optional(pool)
            .await?;

        let vehicle = record.and_then(|v| {
            Some(Vehicle {
                id: v.id,
                radio_call_name: v.radiocallname,
                station: v.station,
            })
        });

        Ok(vehicle)
    }

    pub async fn update(
        pool: &PgPool,
        id: i32,
        radio_call_name: &str,
        station: &str,
    ) -> Result<()> {
        query!(
            "UPDATE vehicle SET radiocallname = $1, station = $2 WHERE id = $3;",
            radio_call_name,
            station,
            id
        )
        .execute(pool)
        .await?;

        Ok(())
    }

    pub async fn delete(pool: &PgPool, id: i32) -> Result<()> {
        query!("DELETE FROM vehicle WHERE id = $1;", id)
            .execute(pool)
            .await?;

        Ok(())
    }
}
