use std::path::PathBuf;

use figment::{
    providers::{Env, Format, Toml},
    Figment,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Settings {
    pub db_path: PathBuf,
    pub api: ApiSettings,
    pub team: TeamSettings,
    pub ui: UiSettings,
    pub rating_weights: RatingWeights,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiSettings {
    pub base_url: String,
    pub api_key: String,
    pub timeout: u64,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TeamSettings {
    pub abbrev: String,
    pub season: i32,
    pub major_league_slots: usize,
    pub minor_league_slots: usize,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct UiSettings {
    pub theme: String,
    pub refresh_interval: u64,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RatingWeights {
    pub hit: f64,
    pub on_base: f64,
    pub total_bases: f64,
    pub home_run: f64,
    pub walk: f64,
    pub strikeout: f64,
    pub double_play: f64,
    pub bp_home_run: f64,
    pub bp_single: f64,
}

impl Default for Settings {
    fn default() -> Self {
        Self {
            db_path: PathBuf::from("data/sba_scout.db"),
            api: ApiSettings::default(),
            team: TeamSettings::default(),
            ui: UiSettings::default(),
            rating_weights: RatingWeights::default(),
        }
    }
}

impl Default for ApiSettings {
    fn default() -> Self {
        Self {
            base_url: "https://sba.manticorum.com/".to_string(),
            api_key: String::new(),
            timeout: 30,
        }
    }
}

impl Default for TeamSettings {
    fn default() -> Self {
        Self {
            abbrev: "WV".to_string(),
            season: 13,
            major_league_slots: 26,
            minor_league_slots: 6,
        }
    }
}

impl Default for UiSettings {
    fn default() -> Self {
        Self {
            theme: "dark".to_string(),
            refresh_interval: 300,
        }
    }
}

impl Default for RatingWeights {
    fn default() -> Self {
        Self {
            hit: 1.0,
            on_base: 0.8,
            total_bases: 0.5,
            home_run: 1.5,
            walk: 0.6,
            strikeout: -0.3,
            double_play: -0.5,
            bp_home_run: 0.3,
            bp_single: 0.1,
        }
    }
}

pub fn load_settings() -> Result<Settings, figment::Error> {
    Figment::new()
        .merge(figment::providers::Serialized::defaults(Settings::default()))
        .merge(Toml::file("settings.toml"))
        .merge(Env::prefixed("SBA_SCOUT_").split("__"))
        .extract()
}
