use clap::ValueEnum;
use siteforge::ArchiveOutputProfile;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum TuiScreen {
    Mode,
    Provider,
    Target,
    SiteOptions,
    HfToken,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum Mode {
    Repos,
    Models,
    Datasets,
    Sites,
}

impl std::fmt::Display for Mode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Mode::Repos => write!(f, "repos"),
            Mode::Models => write!(f, "models"),
            Mode::Datasets => write!(f, "datasets"),
            Mode::Sites => write!(f, "sites"),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum DatasetProvider {
    Hf,
    Zenodo,
}

impl DatasetProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            DatasetProvider::Hf => "Hugging Face Datasets",
            DatasetProvider::Zenodo => "Zenodo",
        }
    }

    pub(crate) fn short_label(self) -> &'static str {
        match self {
            DatasetProvider::Hf => "HF",
            DatasetProvider::Zenodo => "ZEN",
        }
    }
}

impl std::fmt::Display for DatasetProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DatasetProvider::Hf => write!(f, "hf"),
            DatasetProvider::Zenodo => write!(f, "zenodo"),
        }
    }
}

impl From<DatasetProvider> for baseforge::DatasetProvider {
    fn from(value: DatasetProvider) -> Self {
        match value {
            DatasetProvider::Hf => Self::Hf,
            DatasetProvider::Zenodo => Self::Zenodo,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct SiteTuiOptions {
    pub(crate) full_site: bool,
    pub(crate) max_depth: usize,
    pub(crate) max_pages: usize,
    pub(crate) archive_profile: ArchiveOutputProfile,
    pub(crate) render_js: bool,
    pub(crate) render_js_auto: bool,
}

impl Default for SiteTuiOptions {
    fn default() -> Self {
        Self {
            full_site: true,
            max_depth: 2,
            max_pages: 100,
            archive_profile: ArchiveOutputProfile::Full,
            render_js: false,
            render_js_auto: false,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum SiteArchiveProfile {
    Full,
    Agent,
    Lean,
}

impl SiteArchiveProfile {
    pub(crate) fn as_output_profile(self) -> ArchiveOutputProfile {
        match self {
            Self::Full => ArchiveOutputProfile::Full,
            Self::Agent => ArchiveOutputProfile::Agent,
            Self::Lean => ArchiveOutputProfile::Lean,
        }
    }
}

impl From<ArchiveOutputProfile> for SiteArchiveProfile {
    fn from(value: ArchiveOutputProfile) -> Self {
        match value {
            ArchiveOutputProfile::Full => Self::Full,
            ArchiveOutputProfile::Agent => Self::Agent,
            ArchiveOutputProfile::Lean => Self::Lean,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum ModelProvider {
    Hf,
    Ollama,
    Civitai,
}

impl ModelProvider {
    pub(crate) fn label(self) -> &'static str {
        match self {
            ModelProvider::Hf => "Hugging Face",
            ModelProvider::Ollama => "Ollama",
            ModelProvider::Civitai => "CivitAI",
        }
    }

    pub(crate) fn short_label(self) -> &'static str {
        match self {
            ModelProvider::Hf => "HF",
            ModelProvider::Ollama => "OLM",
            ModelProvider::Civitai => "CIV",
        }
    }
}

impl std::fmt::Display for ModelProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ModelProvider::Hf => write!(f, "hf"),
            ModelProvider::Ollama => write!(f, "ollama"),
            ModelProvider::Civitai => write!(f, "civitai"),
        }
    }
}

impl From<ModelProvider> for modelforge::ModelProvider {
    fn from(value: ModelProvider) -> Self {
        match value {
            ModelProvider::Hf => Self::Hf,
            ModelProvider::Ollama => Self::Ollama,
            ModelProvider::Civitai => Self::Civitai,
        }
    }
}
