use crate::lang::CardStatistics;
use crate::repetitions::CardSetSettings;
use rusqlite::Connection;
use std::time::Instant;

pub fn load_stats_of_set(set: &CardSetSettings, connection: &Connection) -> Vec<CardStatistics> {
    let mut stmt = connection
        .prepare("SELECT id, word_id, score, last_opened FROM card_stats WHERE set_id = ?1")
        .unwrap();
    let iter = stmt
        .query_map((set.id,), |row| {
            Ok(CardStatistics {
                id: row.get(0)?,
                word_id: row.get(1)?,
                set_id: set.id,
                score: row.get(2)?,
                last_open: row.get(3)?,
            })
        })
        .unwrap();

    let mut buffer = vec![];
    for word in iter {
        buffer.push(word.unwrap());
    }

    buffer
}

pub fn add_stat_list(stat: &mut Vec<CardStatistics>, connection: &Connection) {
    let inserting = stat
        .iter()
        .map(|stat| {
            format!(
                "({}, {}, {}, {})",
                stat.word_id.to_string(),
                stat.set_id.to_string(),
                stat.score.to_string(),
                stat.last_open.timestamp().to_string()
            )
        })
        .collect::<Vec<_>>()
        .join(", ");
    let query = format!(
        "INSERT INTO card_stats (word_id, set_id, score, last_opened) VALUES {}",
        inserting
    );
    let count = connection.execute(query.as_str(), ());

    if count.is_err() {
        println!("{}", count.unwrap_err());
        return;
    }

    let last_index: u32 = connection
        .query_one(
            "SELECT seq from sqlite_sequence WHERE name == ?1",
            ("card_stats".to_string(),),
            |row| row.get(0),
        )
        .unwrap();

    let start_index = last_index - (count.unwrap() as u32) + 1;

    let mut index = 0;
    for id in start_index..=last_index {
        stat[index].id = id;
        index += 1;
    }
}

// pub fn add_stat(stat: &mut CardStatistics, connection: &Connection) {
//     let time = Instant::now();
//     let index = connection
//         .query_row(
//             "INSERT INTO card_stats (word_id, set_id, score, last_opened) VALUES (?1, ?2, ?3, ?4) RETURNING id",
//             (
//                 &stat.word_id,
//                 &stat.set_id,
//                 &stat.score,
//                 &stat.last_open.timestamp(),
//             ),
//             |row| row.get(0)
//         )
//         .unwrap_or_else(|e| {println!("{}", e); 0});
//
//     stat.id = index;
//     println!("Added stat: {}", time.elapsed().as_millis());
// }

pub fn update_stat_score(stat: &CardStatistics, connection: &Connection) {
    let time = Instant::now();

    connection
        .execute(
            "UPDATE card_stats SET score = ?1, last_opened = ?2 WHERE id = ?3",
            (&stat.score, &stat.last_open.timestamp(), &stat.id),
        )
        .unwrap_or_else(|e| {
            println!("{}", e);
            0
        });
    println!("Updated stat: {}", time.elapsed().as_millis());
}

pub fn delete_stat(stat: &CardStatistics, connection: &Connection) {
    if stat.id == 0 {
        return;
    }
    connection
        .execute("DELETE FROM card_stats WHERE id = ?1", (&stat.id,))
        .unwrap_or_else(|e| {
            println!("{}", e);
            0
        });
}
