use std::sync::Arc;

use anyhow::Result;
use rfactor_sm_reader::{rF2VehicleTelemetry, VehicleScoringInfoV01};
use ui::prelude::*;

use crate::overlay::{rfactor_data::DataReceiver, UiOverlay};

pub struct Pedals {
    gui: Arc<GuiBuilder>,

    brake: Arc<ProgressBar>,
    throttle: Arc<ProgressBar>,
    fuel: Arc<Label>,
    gear: Arc<Label>,
}

impl Pedals {
    pub fn new(gui_handler: &Arc<GuiHandler>) -> Result<Self> {
        const DESC: &str = include_str!("ui_files/pedals.xml");

        let gui = GuiBuilder::from_str(gui_handler, DESC)?;

        let brake = gui.element("brake")?;
        let throttle = gui.element("throttle")?;
        let fuel = gui.element("fuel")?;
        let gear = gui.element("gear")?;

        Ok(Self {
            gui,
            brake,
            throttle,
            fuel,
            gear,
        })
    }
}

impl Drop for Pedals {
    fn drop(&mut self) {
        self.gui.disable().unwrap();
    }
}

impl UiOverlay for Pedals {}

impl DataReceiver for Pedals {
    fn scoring_update(&mut self, _vehicle_scoring: &[VehicleScoringInfoV01]) -> Result<()> {
        Ok(())
    }

    fn telemetry_update(
        &mut self,
        player_id: Option<i32>,
        telemetries: &[rF2VehicleTelemetry],
    ) -> Result<()> {
        match player_id {
            Some(id) => {
                self.gui.enable()?;

                if let Some(telemetry) = telemetries.iter().find(|telemetry| telemetry.id == id) {
                    self.brake
                        .set_progress(telemetry.unfiltered_throttle as f32)?;
                    self.throttle
                        .set_progress(telemetry.unfiltered_throttle as f32)?;
                    self.gear.set_text(telemetry.gear)?;
                    let fuel = telemetry.fuel;
                    self.fuel.set_text(format!("{:.2}", fuel))?;
                }
            }
            None => {
                self.gui.disable()?;
            }
        }

        Ok(())
    }
}