use std::{fs::File, io::Read};

use serde::de::DeserializeOwned;

use crate::{course::story, learner::profile::{self, Learner}};

// pub fn save_learner_progress(learner: &Learner, file: &str) -> Result<(), std::io::Error> {
//     learner.clone().save_to_file(file)?;
//     Ok(())
// }

pub fn get_previous_saves() -> Vec<String> {
    let mut previous_saves = std::fs::read_dir("saves/")
    .unwrap_or_else(|_| {
        std::fs::create_dir_all("saves/").expect("Failed to create the saves/ directory");
        std::fs::read_dir("saves/").expect("Failed to read the saves/ directory")
    })
    .filter_map(|entry| {
    let entry = entry.ok()?;
    let path = entry.path();
    if path.extension()?.to_str()? == "json" {
        let file_content = std::fs::read_to_string(&path).ok()?;
        let learner: Learner = serde_json::from_str(&file_content).ok()?;
        Some(learner.name)
    } else {
        None
    }
    })
    .collect::<Vec<String>>();
    previous_saves.push("Create New".to_string());
    previous_saves
}

pub fn save_to_file(file: &str, learner: &Learner) -> Result<String, std::io::Error> {
    match serde_json::to_string_pretty(learner) {
        Ok(json_data) => match std::fs::write(file, json_data) {
            Ok(_) => Ok(format!("File saved to {}", file.to_string())),
            Err(e) => {
                eprintln!("Error writing to file: {}", e);
                Err(e)
            }
        },
        Err(e) => {
            eprintln!("Error serializing learner: {}", e);
            Err(e.into())
        }
    }
}

pub fn load_from_file<T: DeserializeOwned>(filename: &str) -> Result<T, Box<dyn std::error::Error>> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let data = serde_json::from_str(&contents)?;
    Ok(data)
}

// pub fn load_learner_progress() -> Result<Learner, std::io::Error> {
//     let mut new_session: bool = false;

//     let mut learner = {
//         // Initialize the learner's progress
//         // Check if a save file exists to load previous progress
//         if std::path::Path::new(SAVE_FILE).exists() {
//             match Learner::load_from_file(SAVE_FILE) {
//                 Ok(progress) => {
//                     print_boxed(&format!("Welcome back, {}! Let's continue your journey in FABLE.", progress.name), StatementType::Default );
//                     progress
//                 }
//                 Err(e) => {
//                     new_session = true;
//                     print_boxed(&format!("Couldn't load your save file due to error: {}.\nStarting a new learning experience.", e), StatementType::IncorrectFeedback );
//                     Learner::initialize_learner()
//                 }
//             }
//         } else {
//             new_session = true;
//             // Start a new session
//             print_boxed("
//             Welcome to FABLE, an interactive tutor for formal reasoning.
//             Fallacy ~~~~~~~~~~~~
//             Awareness and ~~~~~~
//             Bias ~~~~~~~~~~~~~~~
//             Learning ~~~~~~~~~~~
//             Environment ~~~~~~~~", StatementType::Default);
//             print_boxed("
//             My name is Francis, and I am here to help you learn about formal reasoning.\n
//             You see, many years ago, my people were nearly wiped out because of a lack of critical thinking.
//             I have been programmed to help you avoid the same fate.\n
//             In the next screen, you can select what you want to study.
//             Choose wisely. The fate of your people depends on it.", StatementType::Default);
//             Learner::initialize_learner()
//         }
//     };
//     if !new_session {
//         learner.display_progress();
//         learner.confirm_course_selection(); // Confirm the course selection after reading the progress
//     }

//     let json_data = std::fs::read_to_string(SAVE_FILE)?;
//     let progress: Learner = serde_json::from_str(&json_data)?;
//     Ok(progress)
// }


// pub fn load_learner_progress() -> Result<Learner, std::io::Error> {
//     let json_data = fs::read_to_string(SAVE_FILE)?;
//     let progress: Learner = serde_json::from_str(&json_data)?;
//     Ok(progress)
// }

pub fn sanitize_name(name: &str) -> String {
    name.replace(|c: char| !c.is_alphanumeric(), "_").to_lowercase()
}

pub fn parse_unit(filename: &str) -> Result<story::UnitStory, Box<dyn std::error::Error>> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let data = serde_json::from_str(&contents)?;
    Ok(data)
}