use serde_derive::{Deserialize, Serialize};
use crate::config::PostBody::Description;

#[derive(Serialize, Deserialize, Clone, Debug)]
pub(crate) struct Config {
    pub(crate) instance: String,
    pub(crate) username: String,
    pub(crate) password: String,
    pub(crate) status_post_url: Option<String>,
    pub(crate) config_reload_seconds: u32,
    pub(crate) protected_communities: Vec<String>,
    pub(crate) series: Vec<SeriesConfig>,
}

impl Config {
    pub(crate) fn load() -> Self {
        let cfg: Self = match confy::load(env!("CARGO_PKG_NAME"), "config") {
            Ok(data) => data,
            Err(e) => panic!("config.toml not found: {e}"),
        };

        if cfg.instance.is_empty() {
            panic!("bot instance not set!")
        }

        if cfg.username.is_empty() {
            panic!("bot username not set!")
        }

        if cfg.password.is_empty() {
            panic!("bot password not provided!")
        }

        cfg.series.iter().for_each(|series| {
            if series.prepub_community.post_body == Description {
                panic!("'Description' type Post Body only supported for Volumes!")
            }
        });
        cfg
    }
}

impl Default for Config {
    fn default() -> Self {
        Config {
            instance: "".to_owned(),
            username: "".to_owned(),
            password: "".to_owned(),
            status_post_url: None,
            config_reload_seconds: 21600,
            protected_communities: vec![],
            series: vec![]
        }
    }
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) struct SeriesConfig {
    pub(crate) slug: String,
    pub(crate) parted: bool,
    pub(crate) prepub_community: PostConfig,
    pub(crate) volume_community: PostConfig,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) struct PostConfig {
    pub(crate) name: String,
    pub(crate) pin_settings: PinConfig,
    pub(crate) post_body: PostBody,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub(crate) struct PinConfig {
    pub(crate) pin_new_post_local: bool,
    pub(crate) pin_new_post_community: bool,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "body_type", content = "body_content")]
pub(crate) enum PostBody {
    None,
    Description,
    Custom(String),
}