use crate::devices::device::DeviceRelayID;
use crate::energy::{energy_actor, relay_state_history};
use crate::server::WebEnergyActor;
use crate::server::custom_error::HttpResult;
use actix_web::{HttpResponse, web};

#[derive(serde::Deserialize)]
pub struct LegacyStateRelay {
    id: DeviceRelayID,
}

/// Legacy relay state
#[derive(serde::Serialize)]
pub struct LegacyState {
    /// Indicates if relay is on or off
    is_on: bool,
    /// Relay name
    name: String,
    /// Duration since last change of state
    r#for: usize,
    /// Current grid consumption
    prod: i32,
    /// Total uptime since last reset
    total_uptime: usize,
    /// Required uptime during a day
    ///
    /// Will be 0 if there is no daily requirements
    required_uptime: usize,
}

/// Get the state of a relay, adapted for old system components
pub async fn legacy_state(
    energy_actor: WebEnergyActor,
    path: web::Path<LegacyStateRelay>,
) -> HttpResult {
    let Some(relay) = energy_actor
        .send(energy_actor::GetSingleRelay(path.id))
        .await?
    else {
        return Ok(HttpResponse::NotFound().body("Relay not found!"));
    };

    let all_states = energy_actor.send(energy_actor::GetAllRelaysState).await?;
    let Some(state) = all_states.into_iter().find(|r| r.id == path.id) else {
        return Ok(HttpResponse::InternalServerError().body("Relay status unavailable!"));
    };

    let production = energy_actor.send(energy_actor::GetCurrConsumption).await?;

    let total_uptime = relay_state_history::relay_total_runtime_adjusted(&relay);

    Ok(HttpResponse::Ok().json(LegacyState {
        name: relay.name,
        is_on: state.on,
        r#for: state.r#for.min(3600 * 24 * 7),
        prod: production,
        total_uptime,
        required_uptime: relay.daily_runtime.map(|r| r.min_runtime).unwrap_or(0),
    }))
}