use crate::lang::KanaSet;
use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page};
use crate::quiz::QuizMessage::*;
use crate::styling::*;
use crate::{RootMessage, USER_FONT};
use iced::widget::*;
use iced::{Element, Fill, Task, alignment};
use rand::seq::SliceRandom;

#[derive(Clone, Debug)]
pub struct QuizState {
    kana: String,
    current_roman: String,
    correct_roman: String,
    pub(crate) set: KanaSet,
    queue: Vec<(String, String)>,
    score: Score,
    is_help: bool,
}

impl NavigatedPage<QuizMessage> for QuizState {
    fn navigate(&mut self, message: &QuizMessage) -> Option<Page> {
        if let Back = message {
            Some(PreviousPage)
        } else {
            None
        }
    }

    fn navigated(&mut self) {}

    fn update(&mut self, message: QuizMessage) -> Task<RootMessage> {
        match message {
            ContentChanged(content) => {
                if content.contains("`") {
                    self.is_help = true;
                    self.score.fail += 1;

                    return Task::none();
                }
                self.current_roman = content;
                if self.correct_roman == self.current_roman {
                    if !self.is_help {
                        self.score.correct += 1;
                    }

                    self.is_help = false;
                    self.score.total += 1;
                    self.update_showed()
                } else if self.current_roman.len() == self.correct_roman.len() {
                    self.score.total += 1;
                    self.score.fail += 1;
                    self.update_showed()
                }
            }
            Back => {}
        }
        Task::none()
    }

    fn view(&self) -> Element<'_, QuizMessage> {
        container(
            iced::widget::column![
                row![
                    text!("{}", self.kana.to_lowercase())
                        .size(54)
                        .font(USER_FONT),
                    text!(
                        "{}",
                        if self.is_help {
                            self.correct_roman.clone()
                        } else {
                            String::new()
                        }
                    ),
                ]
                .align_y(alignment::Vertical::Center)
                .spacing(20),
                text_input("Романдзи", &self.current_roman)
                    .size(28)
                    .width(150)
                    .on_input(ContentChanged),
                score_display(&self.score),
                button("Закончить").style(jl_button).on_press(Back),
            ]
            .spacing(DEFAULT_SPACING)
            .align_x(alignment::Horizontal::Center),
        )
        .center_y(Fill)
        .center_x(Fill)
        .into()
    }
}

fn score_display<'a, T: 'a>(score: &Score) -> Element<'a, T> {
    row![
        text!("{}", score.total.to_string()).size(25),
        text!("{}", score.correct.to_string())
            .size(25)
            .color(iced::Color::from_rgb8(60, 170, 60)),
        text!("{}", score.fail.to_string())
            .color(iced::Color::from_rgb8(255, 79, 0))
            .size(25),
    ]
    .spacing(DEFAULT_SPACING)
    .into()
}

impl QuizState {
    pub(crate) fn new() -> QuizState {
        QuizState {
            kana: "ぁ".to_string(),
            correct_roman: "a".to_string(),
            is_help: false,
            current_roman: "".to_string(),
            set: KanaSet::hiragana(),
            queue: Vec::new(),
            score: Score {
                total: 0,
                correct: 0,
                fail: 0,
            },
        }
    }
}

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

impl QuizState {
    fn update_showed(&mut self) {
        self.current_roman = String::new();
        let queue = &mut self.queue;

        if queue.is_empty() {
            for pair in self.set.list() {
                queue.push(pair);
            }

            queue.shuffle(&mut rand::rng());
        }

        let pair = self.queue.pop().unwrap();
        self.kana = pair.0;
        self.correct_roman = pair.1;
    }
}
#[derive(Debug, Clone)]
pub enum QuizMessage {
    ContentChanged(String),
    Back,
}

#[derive(Default, Debug, Clone)]
pub struct Score {
    pub(crate) total: i32,
    pub(crate) correct: i32,
    pub(crate) fail: i32,
}
