use serde::{Deserialize, Serialize};

// Re-export compatible wrapper types that maintain String IDs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Workspace {
    pub id: String,
    pub slug: String,
    pub name: String,
}

impl From<crate::doqium_data_client::models::Workspace> for Workspace {
    fn from(w: crate::doqium_data_client::models::Workspace) -> Self {
        Workspace {
            id: w.id.to_string(),
            slug: w.slug,
            name: w.name,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Notebook {
    pub id: String,
    #[serde(rename = "workspaceId")]
    pub workspace_id: String,
    pub slug: String,
    pub name: String,
}

impl From<crate::doqium_data_client::models::Notebook> for Notebook {
    fn from(n: crate::doqium_data_client::models::Notebook) -> Self {
        Notebook {
            id: n.id.to_string(),
            workspace_id: n.workspace_id.to_string(),
            slug: n.slug,
            name: n.name,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NoteMetadata {
    pub id: String,
    #[serde(rename = "type")]
    pub note_type: String,
    pub title: String,
    pub slug: String,
    #[serde(default)]
    pub labels: Vec<String>,
    pub favorite: bool,
    pub trashed: bool,
    pub archived: bool,
    pub public: bool,
    pub created: String,
    pub modified: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub revision: Option<u32>,
}

impl From<crate::doqium_data_client::models::NoteMetadata> for NoteMetadata {
    fn from(m: crate::doqium_data_client::models::NoteMetadata) -> Self {
        NoteMetadata {
            id: m.id.map(|id| id.to_string()).unwrap_or_default(),
            note_type: serde_json::to_value(&m.r#type)
                .ok()
                .and_then(|v| v.as_str().map(String::from))
                .unwrap_or_else(|| "text".to_string()),
            title: m.title,
            slug: m.slug,
            labels: m.labels,
            favorite: m.favorite,
            trashed: m.trashed,
            archived: m.archived,
            public: m.public,
            created: m.created,
            modified: m.modified,
            revision: m.revision.map(|r| r as u32),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Note {
    pub metadata: NoteMetadata,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub content: Option<String>,
}

impl From<crate::doqium_data_client::models::Note> for Note {
    fn from(n: crate::doqium_data_client::models::Note) -> Self {
        Note {
            metadata: (*n.metadata).clone().into(),
            content: Some(n.content),
        }
    }
}

pub struct EnrichedNotebook {
    pub notebook: Notebook,
    pub workspace_name: String,
    pub workspace_slug: String,
}

pub struct EnrichedNote {
    pub note: Note,
    pub notebook_name: String,
    pub notebook_slug: String,
    pub workspace_name: String,
    pub workspace_slug: String,
}

#[derive(Debug)]
pub struct AdminUser {
    pub id: String,
    pub username: String,
    pub name: String,
    pub email: String,
    #[allow(dead_code)]
    pub email_validated: Option<String>,
    pub blocked: bool,
    pub blocking_reason: Option<String>,
    #[allow(dead_code)]
    pub blocked_at: Option<String>,
    #[allow(dead_code)]
    pub plan: Option<String>,
    #[allow(dead_code)]
    pub created: String,
    #[allow(dead_code)]
    pub modified: String,
}

impl From<crate::doqium_auth_client::models::AdminListUsers200ResponseInner> for AdminUser {
    fn from(user: crate::doqium_auth_client::models::AdminListUsers200ResponseInner) -> Self {
        AdminUser {
            id: user.id.map(|id| id.to_string()).unwrap_or_default(),
            username: user.username.unwrap_or_default(),
            name: user.name.unwrap_or_default(),
            email: user.email.unwrap_or_default(),
            email_validated: user.email_validated.and_then(|v| v),
            blocked: user.blocked.unwrap_or_default(),
            blocking_reason: user.blocking_reason.and_then(|v| v),
            blocked_at: user.blocked_at.and_then(|v| v),
            plan: user.plan.and_then(|v| v),
            created: user.created.unwrap_or_default(),
            modified: user.modified.unwrap_or_default(),
        }
    }
}
