use chrono::NaiveTime;
use sqlx::{query, PgPool};

use super::Result;

pub struct VehicleAssignement {
    pub event_id: i32,
    pub vehicle_id: i32,
    pub start_time: NaiveTime,
    pub end_time: NaiveTime,
}

impl VehicleAssignement {
    pub async fn create(
        pool: &PgPool,
        event_id: i32,
        vehicle_id: i32,
        start_time: NaiveTime,
        end_time: NaiveTime,
    ) -> Result<()> {
        query!(
            "INSERT INTO vehicleassignement (eventId, vehicleId, startTime, endTime) VALUES ($1, $2, $3, $4);",
            event_id,
            vehicle_id,
            start_time,
            end_time
        )
        .execute(pool)
        .await?;

        Ok(())
    }

    pub async fn read(
        pool: &PgPool,
        event_id: i32,
        vehicle_id: i32,
    ) -> Result<Option<VehicleAssignement>> {
        let record = query!("SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1 AND vehicleAssignement.vehicleId = $2;", event_id, vehicle_id).fetch_optional(pool)
            .await?;

        let vehicle_assignment = record.and_then(|r| Some(VehicleAssignement {
                event_id: r.eventid,
                vehicle_id: r.vehicleid,
                start_time: r.starttime,
                end_time: r.endtime,
        }));

        Ok(vehicle_assignment)
    }

    pub async fn read_all_by_event(
        pool: &PgPool,
        event_id: i32,
    ) -> Result<Vec<VehicleAssignement>> {
        let records = query!(
            "SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1;",
            event_id
        )
        .fetch_all(pool)
        .await?;

        let vehicle_assignments = records
            .iter()
            .map(|r| VehicleAssignement {
                event_id: r.eventid,
                vehicle_id: r.vehicleid,
                start_time: r.starttime,
                end_time: r.endtime,
            })
            .collect();

        Ok(vehicle_assignments)
    }

    pub async fn read_all_by_vehicle(
        pool: &PgPool,
        vehicle_id: i32,
    ) -> Result<Vec<VehicleAssignement>> {
        let records = query!(
            "SELECT * FROM vehicleAssignement WHERE vehicleAssignement.vehicleId = $1;",
            vehicle_id
        )
        .fetch_all(pool)
        .await?;

        let vehicle_assignments = records
            .iter()
            .map(|r| VehicleAssignement {
                event_id: r.eventid,
                vehicle_id: r.vehicleid,
                start_time: r.starttime,
                end_time: r.endtime,
            })
            .collect();

        Ok(vehicle_assignments)
    }

    pub async fn delete(pool: &PgPool, event_id: i32, vehicle_id: i32) -> Result<()> {
        query!(
            "DELETE FROM vehicleassignement WHERE eventId = $1 AND vehicleId = $2;",
            event_id,
            vehicle_id
        )
        .execute(pool)
        .await?;

        Ok(())
    }
}
