use color_eyre::Result;
use ratatui::{
    layout::Rect,
    style::{Style, Stylize},
    text::Span,
    widgets::Paragraph,
    Frame,
};

use super::Component;
use crate::{
    action::Action,
    widgets::{DotSpinner, OghamCenter, VerticalBlocks}
};

#[derive(Debug, Clone, PartialEq)]
pub struct Health {
    name: Option<String>,
    peers: Option<usize>,
    is_syncing: bool, 
    should_have_peers: bool,
    tx_pool_length: usize,
    validators_count: u32,
    nominators_count: u32,
}

impl Default for Health {
    fn default() -> Self {
        Self::new()
    }
}

impl Health {
    pub fn new() -> Self {
        Self {
            name: None,
            peers: None,
            is_syncing: true,
            should_have_peers: false,
            tx_pool_length: 0,
            validators_count: 0,
            nominators_count: 0,
        }
    }

    pub fn is_syncing_as_string(&self) -> String {
        if self.is_syncing { 
            format!("syncing {}", VerticalBlocks::default().to_string())
        } else { 
            String::from("synced")
        }
    }

    pub fn peers_as_string(&self) -> String {
        match self.peers {
            Some(peers) => peers.to_string(),
            None => DotSpinner::default().to_string(),
        }
    }

    pub fn name_as_string(&self) -> String {
        match &self.name {
            Some(name) => name.clone(),
            None => OghamCenter::default().to_string(),
        }
    }
}

impl Component for Health {
    fn update(&mut self, action: Action) -> Result<Option<Action>> {
        match action {
            Action::SetSystemHealth(peers, is_syncing, should_have_peers) => {
                self.peers = peers;
                self.is_syncing = is_syncing;
                self.should_have_peers = should_have_peers;
            },
            Action::SetNodeName(name) => self.name = name,
            Action::SetPendingExtrinsicsLength(length) => self.tx_pool_length = length,
            Action::NominatorsNumber(number) => self.nominators_count = number,
            Action::ValidatorsNumber(number) => self.validators_count = number,
            _ => {}
        };
        Ok(None)
    }

    fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
        let [place, _] = super::header_layout(area);

        let message = format!("{:^12} | tx.pool: {:^3} | peers: {:^3} | {:^9} | validators {:^4} | nominators {:^4} |", 
            self.name_as_string(),
            self.tx_pool_length,
            self.peers_as_string(),
            self.is_syncing_as_string(),
            self.validators_count,
            self.nominators_count);

        let span = Span::styled(message, Style::new().dim());
        let paragraph = Paragraph::new(span).left_aligned();
        frame.render_widget(paragraph, place);
        Ok(())
    }
}