use crossterm::event::{KeyEvent, MouseEvent};
use ratatui::{Frame, layout::Rect};
use tokio::sync::mpsc::UnboundedSender;

use super::Component;
use crate::{action::Action, config::Config, state::App as DiffApp};

pub struct DiffView {
    pub state: DiffApp,
    #[allow(dead_code)]
    config: Config,
}

impl DiffView {
    pub fn new(state: DiffApp) -> Self {
        Self {
            state,
            config: Config::default(),
        }
    }
}

impl Component for DiffView {
    fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> color_eyre::Result<()> {
        self.state.action_tx = Some(tx);
        Ok(())
    }

    fn register_config_handler(&mut self, config: Config) -> color_eyre::Result<()> {
        self.config = config;
        Ok(())
    }

    fn handle_key_event(&mut self, key: KeyEvent) -> color_eyre::Result<Option<Action>> {
        crate::keys::handle(&mut self.state, key);
        if self.state.should_quit {
            return Ok(Some(Action::Quit));
        }
        if self.state.pending_reload {
            self.state.pending_reload = false;
            return Ok(Some(Action::Reload));
        }
        if self.state.pending_open_editor {
            self.state.pending_open_editor = false;
            return Ok(Some(Action::OpenEditor));
        }
        Ok(None)
    }

    fn handle_mouse_event(&mut self, mouse: MouseEvent) -> color_eyre::Result<Option<Action>> {
        crate::event::handle_mouse(&mut self.state, mouse);
        Ok(None)
    }

    fn update(&mut self, action: Action) -> color_eyre::Result<Option<Action>> {
        if matches!(action, Action::Tick) {
            crate::event::tick(&mut self.state);
        }
        Ok(None)
    }

    fn draw(&mut self, frame: &mut Frame, _area: Rect) -> color_eyre::Result<()> {
        crate::ui::render(frame, &mut self.state);
        Ok(())
    }
}
