use crate::dictionary::app_data_dir;
use crate::lang::{WordData, WordOpenMode};
use crate::{AppState, NavigatedPage, Page, RootMessage};
use chrono::{DateTime, Utc};
use iced::widget::*;
use iced::{Element, Fill, Left, Task};
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::sync::{Arc, Mutex};
use HistoryMessage::Back;

#[derive(Clone)]
pub struct HistoryState {
    set_id: u32,
    list: Vec<HistoryItem>,
}

impl NavigatedPage<HistoryMessage> for HistoryState {
    fn navigate(&self, message: &HistoryMessage) -> Option<Page> {
        match message {
            Back => Some(Page::PreviousPage),
            _ => None,
        }
    }
}

impl HistoryState {
    pub fn new(id: u32, state: Arc<Mutex<AppState>>) -> Self {
        Self {
            set_id: id,
            list: get_history_of_set(id, &state.lock().unwrap().dictionary),
        }
    }

    pub fn update(&mut self, message: HistoryMessage) -> Task<RootMessage> {
        Task::none()
    }

    pub fn view(&self) -> Element<'_, HistoryMessage> {
        container(
            iced::widget::column![
                button("Назад").on_press(HistoryMessage::Back),
                // column![
                //
                // ]
                // .height(Fill)
                // .width(Fill)
            ]
            .align_x(Left)
            .width(Fill),
        )
        .center_x(Fill)
        .padding(10)
        .into()
    }
}

fn get_history_of_set(id: u32, words: &Vec<WordData>) -> Vec<HistoryItem> {
    let app_dir = app_data_dir();
    let head = app_dir.clone().join(format!("set_{}_history.csv", id));
    let tail = app_dir.clone().join(format!("set_{}_history.csv", id));
    let mut lines = Vec::new();
    if tail.exists() {
        let reader = BufReader::new(File::open(tail).unwrap());
        for line in reader.lines() {
            lines.push(line.unwrap());
        }
    }

    if head.exists() {
        let reader = BufReader::new(File::open(head).unwrap());
        for line in reader.lines() {
            lines.push(line.unwrap());
        }
    }

    parse_history_items(lines, words)
}

fn parse_history_items(strings: Vec<String>, words: &Vec<WordData>) -> Vec<HistoryItem> {
    let mut items = Vec::with_capacity(strings.len());
    for string in strings {
        if let [time, word, mode, before, after] = string.split(';').collect::<Vec<&str>>()[..] {
            items.push(HistoryItem {
                timestamp: DateTime::from_timestamp(time.parse().unwrap(), 0).unwrap(),
                word: words
                    .iter()
                    .find(|w| w.id == word.parse::<u32>().unwrap())
                    .unwrap()
                    .clone(),
                mode: match mode.parse::<u8>().unwrap() {
                    2 => WordOpenMode::Hard,
                    3 => WordOpenMode::Ok,
                    4 => WordOpenMode::Easy,
                    _ => WordOpenMode::None,
                },
                before: before.parse().unwrap(),
                after: after.parse().unwrap(),
            });
        }
    }

    items
}

#[derive(Clone)]
pub enum HistoryMessage {
    Back,
}

#[derive(Clone)]
pub struct HistoryItem {
    timestamp: DateTime<Utc>,
    word: WordData,
    mode: WordOpenMode,
    before: u8,
    after: u8,
}
