#![windows_subsystem = "windows"]
mod data_provider;
mod dictionary;
mod dictionary_test;
mod history;
pub mod import;
mod lang;
pub mod navigation;
mod quiz;
mod randomizer;
mod repetition;
mod repetition_settings;
mod repetitions;
mod selector;
pub mod styling;
mod sync;
mod word;
mod writing;

use crate::RootMessage::Keyboard;
use crate::data_provider::card_sets::load_sets;
use crate::data_provider::settings::get_setting;
use crate::data_provider::sqlite::default_connection;
use crate::data_provider::words::{load_word_groups, load_words};
use crate::lang::{DeckSettings, Id, WordData, WordGroup};
use crate::navigation::{AppSettings, RootMessage, ScreenState};
use crate::quiz::*;
use chrono::NaiveDate;
use hashbrown::HashMap;
use iced::{Font, window};
use iced::{Subscription, Theme, keyboard};
use iced_core::Size;
use iced_core::window::Position;
#[cfg(target_os = "linux")]
use iced_core::window::settings::PlatformSpecific;
use mimalloc::MiMalloc;
use rusqlite::Connection;
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;

const USER_FONT: Font = Font::with_name("Noto Sans JP");

fn main() -> iced::Result {
    println!("Welcome to JapLearn");
    iced::application(ScreenState::boot, ScreenState::update, ScreenState::view)
        .window(window_settings())
        .subscription(subscription)
        .title("JapLearn")
        .settings(iced::Settings {
            default_text_size: iced::Pixels(18.0),
            ..iced::Settings::default()
        })
        .font(include_bytes!("../noto.ttf"))
        .default_font(USER_FONT)
        .theme(Theme::GruvboxDark)
        .run()
}

#[allow(unused_mut)]
fn window_settings() -> window::Settings {
    let mut settings = window::Settings {
        position: Position::Centered,
        min_size: Some(Size::new(700.0_f32, 700.0_f32)),
        ..Default::default()
    };

    #[cfg(target_os = "linux")]
    {
        settings.platform_specific = PlatformSpecific {
            application_id: "JapLearn".to_string(),
            override_redirect: false,
        };
    }

    settings
}

fn subscription(_state: &ScreenState) -> Subscription<RootMessage> {
    keyboard::listen().map(Keyboard)
}

pub struct AppState {
    pub dictionary: Vec<WordData>,
    pub decks: Vec<DeckSettings>,
    pub word_groups: Vec<WordGroup>,
    pub connection: Connection,
    pub sync_data: AppSettings,
    pub activity: HashMap<Id, Vec<(NaiveDate, u32)>>,
}

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

impl AppState {
    pub fn new() -> Self {
        Self {
            dictionary: vec![],
            decks: vec![],
            word_groups: vec![],
            connection: default_connection(),
            sync_data: AppSettings {
                key: None,
                auto_web_fetch: false,
            },
            activity: Default::default(),
        }
    }
}

fn fill_state(state: &mut AppState) {
    let list = load_words(&state.connection);
    let sets = load_sets(&state.connection);
    let groups = load_word_groups(&state.connection);
    let setting = load_settings(&state.connection);

    state.dictionary = list;
    state.decks = sets;
    state.word_groups = groups;
    state.sync_data = setting
}

fn load_settings(connection: &Connection) -> AppSettings {
    let key = get_setting("SYNC_KEY".to_string(), connection);
    let fetch = get_setting("AUTO_WEB_FETCH".to_string(), connection)
        .unwrap_or("false".to_string())
        .parse::<bool>()
        .unwrap();
    AppSettings {
        key,
        auto_web_fetch: fetch,
    }
}
