use std::process::Child;

use serde::Deserialize;

use crate::types::ModelProvider;

#[derive(Debug, Clone)]
pub(crate) struct RepoItem {
    pub(crate) name: String,
    pub(crate) full_name: String,
    pub(crate) clone_url: String,
}

#[derive(Debug, Deserialize)]
pub(crate) struct RepoResponse {
    pub(crate) name: String,
    #[serde(rename = "full_name")]
    pub(crate) full_name: String,
    #[serde(rename = "clone_url")]
    pub(crate) clone_url: String,
    pub(crate) private: bool,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub(crate) struct ModelItem {
    pub(crate) id: String,
    pub(crate) downloads: u64,
    pub(crate) pipeline_tag: Option<String>,
    pub(crate) last_modified: Option<String>,
    pub(crate) provider: ModelProvider,
    pub(crate) download_url: Option<String>,
    pub(crate) size: Option<u64>,
}

#[derive(Debug, Deserialize)]
pub(crate) struct HfModelResponse {
    #[serde(rename = "modelId", default)]
    pub(crate) model_id: Option<String>,
    #[serde(default)]
    pub(crate) id: String,
    #[serde(default)]
    pub(crate) downloads: u64,
    #[serde(rename = "pipeline_tag", default)]
    pub(crate) pipeline_tag: Option<String>,
    #[serde(rename = "lastModified", default)]
    pub(crate) last_modified: Option<String>,
}

#[derive(Debug, Deserialize)]
pub(crate) struct OllamaModelResponse {
    pub(crate) models: Vec<OllamaModel>,
}

#[derive(Debug, Deserialize)]
pub(crate) struct OllamaModel {
    pub(crate) name: String,
    #[serde(default)]
    pub(crate) size: u64,
    #[serde(default)]
    pub(crate) modified_at: String,
}

#[derive(Debug, Deserialize)]
pub(crate) struct CivitaiModelResponse {
    pub(crate) items: Vec<CivitaiModel>,
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub(crate) struct CivitaiModel {
    pub(crate) id: u64,
    pub(crate) name: String,
    #[serde(default)]
    pub(crate) downloads: u64,
    #[serde(rename = "type", default)]
    pub(crate) model_type: Option<String>,
    #[serde(default)]
    pub(crate) description: Option<String>,
    pub(crate) model_versions: Option<Vec<CivitaiModelVersion>>,
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub(crate) struct CivitaiModelVersion {
    pub(crate) id: u64,
    pub(crate) name: Option<String>,
    #[serde(default)]
    pub(crate) download_url: Option<String>,
    #[serde(default)]
    pub(crate) size: Option<u64>,
}

#[derive(Debug, Clone)]
pub(crate) enum CloneStatus {
    Cloned,
    Skipped,
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum BatchState {
    Pending,
    Running,
    Done,
    Skipped,
    Failed,
}

#[derive(Debug)]
pub(crate) enum CloneAction {
    Skipped,
    Running(Child),
}

#[derive(Debug, Default)]
pub(crate) struct CloneSummary {
    pub(crate) cloned: usize,
    pub(crate) skipped: usize,
    pub(crate) failed: Vec<String>,
}

#[derive(Debug, Default)]
pub(crate) struct UiState {
    pub(crate) show_details: bool,
    pub(crate) abort_requested: bool,
    pub(crate) panel_lines: usize,
}
