use core::fmt::Write;

use embedded_graphics::{
    pixelcolor::Gray8,
    prelude::{DrawTarget, OriginDimensions},
};
use heapless::String;

use crate::input::InputEvent;

use super::ScreenUpdate;
use crate::ui::{books::BOOKS, frame::Frame, RefreshHint};

pub(crate) struct LibraryScreen {
    selected: usize,
}

#[derive(Clone, Copy)]
pub(crate) enum LibraryAction {
    None,
    OpenOnboarding,
    OpenReader { book_index: usize },
}

impl LibraryScreen {
    pub fn new() -> Self {
        Self { selected: 0 }
    }

    pub fn new_with_selected(selected: usize) -> Self {
        Self {
            selected: selected.min(BOOKS.len() - 1),
        }
    }

    pub fn update(&mut self, event: InputEvent) -> ScreenUpdate<LibraryAction> {
        match event {
            InputEvent::Up => {
                self.selected = if self.selected == 0 {
                    BOOKS.len() - 1
                } else {
                    self.selected - 1
                };
                ScreenUpdate::new(true, RefreshHint::Fast, LibraryAction::None)
            }
            InputEvent::Down => {
                self.selected = (self.selected + 1) % BOOKS.len();
                ScreenUpdate::new(true, RefreshHint::Fast, LibraryAction::None)
            }
            InputEvent::Select => ScreenUpdate::new(
                true,
                RefreshHint::Full,
                LibraryAction::OpenReader {
                    book_index: self.selected,
                },
            ),
            InputEvent::Back => {
                ScreenUpdate::new(true, RefreshHint::Full, LibraryAction::OpenOnboarding)
            }
            _ => ScreenUpdate::new(false, RefreshHint::None, LibraryAction::None),
        }
    }

    pub fn render<D>(&self, frame: &mut Frame<'_, D>) -> Result<(), D::Error>
    where
        D: DrawTarget<Color = Gray8> + OriginDimensions,
    {
        frame.title("Library")?;
        frame.small(58, "Mock book list")?;

        let mut y = 100;
        for (index, book) in BOOKS.iter().enumerate() {
            let marker = if index == self.selected { ">" } else { " " };
            let mut row = String::<96>::new();
            let _ = write!(row, "{} {} - {}", marker, book.title, book.author);
            frame.body(y, row.as_str())?;
            y += 38;
        }

        frame.small(
            274,
            "Book sync and storage will plug in behind this screen.",
        )?;
        frame.footer("Up/Down move Select open Back WiFi")
    }
}
