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 ReaderScreen {
    book_index: usize,
    page_index: usize,
    show_help: bool,
}

#[derive(Clone, Copy)]
pub(crate) enum ReaderAction {
    None,
    OpenLibrary { selected_book: usize },
}

impl ReaderScreen {
    pub fn new(book_index: usize) -> Self {
        Self {
            book_index,
            page_index: 0,
            show_help: false,
        }
    }

    pub fn update(&mut self, event: InputEvent) -> ScreenUpdate<ReaderAction> {
        match event {
            InputEvent::Up => {
                if self.page_index > 0 {
                    self.page_index -= 1;
                    self.show_help = false;
                    ScreenUpdate::new(true, RefreshHint::Fast, ReaderAction::None)
                } else {
                    ScreenUpdate::new(false, RefreshHint::None, ReaderAction::None)
                }
            }
            InputEvent::Down => {
                let last_page = BOOKS[self.book_index].pages.len() - 1;
                if self.page_index < last_page {
                    self.page_index += 1;
                    self.show_help = false;
                    ScreenUpdate::new(true, RefreshHint::Fast, ReaderAction::None)
                } else {
                    ScreenUpdate::new(false, RefreshHint::None, ReaderAction::None)
                }
            }
            InputEvent::Select => {
                self.show_help = !self.show_help;
                ScreenUpdate::new(true, RefreshHint::Fast, ReaderAction::None)
            }
            InputEvent::Back => ScreenUpdate::new(
                true,
                RefreshHint::Full,
                ReaderAction::OpenLibrary {
                    selected_book: self.book_index,
                },
            ),
            _ => ScreenUpdate::new(false, RefreshHint::None, ReaderAction::None),
        }
    }

    pub fn render<D>(&self, frame: &mut Frame<'_, D>) -> Result<(), D::Error>
    where
        D: DrawTarget<Color = Gray8> + OriginDimensions,
    {
        let book = &BOOKS[self.book_index];
        let mut heading = String::<96>::new();
        let _ = write!(heading, "{} - {}", book.title, book.author);

        frame.title("Reader")?;
        frame.small(58, heading.as_str())?;
        frame.paragraph(100, book.pages[self.page_index])?;

        let mut page_line = String::<48>::new();
        let _ = write!(
            page_line,
            "Page {} of {}",
            self.page_index + 1,
            book.pages.len()
        );
        frame.small(392, page_line.as_str())?;

        if self.show_help {
            frame.small(346, "Controls: Up prev, Down next, Back library")?;
        }

        frame.footer("Up/Down page Select controls Back library")
    }
}
