use crate::api::{EnrichedNotebook, Notebook};
use crate::apis::{notebooks_api, workspaces_api};
use anyhow::Result;

pub async fn list_notebooks(token: &str) -> Result<Vec<Notebook>> {
    notebooks_api::list_notebooks(token).await
}

pub async fn list_enriched_notebooks(token: &str) -> Result<Vec<EnrichedNotebook>> {
    let workspaces = workspaces_api::list_workspaces(token).await?;
    let notebooks = list_notebooks(token).await?;

    let mut enriched = Vec::new();
    for notebook in notebooks {
        let workspace = workspaces.iter().find(|w| w.id == notebook.workspace_id);

        let workspace_name = workspace
            .map(|w| w.name.clone())
            .unwrap_or_else(|| "Unknown".to_string());

        let workspace_slug = workspace
            .map(|w| w.slug.clone())
            .unwrap_or_else(|| "unknown".to_string());

        enriched.push(EnrichedNotebook {
            notebook,
            workspace_name,
            workspace_slug,
        });
    }

    Ok(enriched)
}

pub async fn create_notebook(token: &str, workspace_id: &str, name: &str) -> Result<String> {
    notebooks_api::create_notebook(token, workspace_id, name).await
}

pub async fn resolve_notebook_id(token: &str, selector: &str) -> Result<String> {
    if selector.len() == 36 && selector.contains('-') {
        return Ok(selector.to_string());
    }

    if selector.starts_with("@notebook[") {
        let parsed = crate::selector::parse_notebook_selector(selector)?;
        let (workspace_slug, notebook_slug, notebook_id) = parsed;

        if let Some(nb_id) = notebook_id {
            return Ok(nb_id);
        }

        let workspaces = workspaces_api::list_workspaces(token).await?;
        let notebooks = list_notebooks(token).await?;

        let matching_notebooks: Vec<_> = notebooks
            .iter()
            .filter(|nb| {
                if let Some(ref slug) = notebook_slug {
                    if &nb.slug != slug {
                        return false;
                    }
                }

                if let Some(ref ws_slug) = workspace_slug {
                    if let Some(workspace) = workspaces.iter().find(|w| w.id == nb.workspace_id) {
                        if &workspace.slug != ws_slug {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }

                true
            })
            .collect();

        if matching_notebooks.is_empty() {
            anyhow::bail!("No notebook found matching selector: {}", selector);
        } else if matching_notebooks.len() > 1 {
            anyhow::bail!(
                "Multiple notebooks found matching selector: {}. Please specify workspace.",
                selector
            );
        }

        Ok(matching_notebooks[0].id.clone())
    } else {
        let notebooks = list_notebooks(token).await?;
        let notebook = notebooks
            .iter()
            .find(|n| n.slug == selector)
            .ok_or_else(|| anyhow::anyhow!("Notebook '{}' not found", selector))?;
        Ok(notebook.id.clone())
    }
}

pub async fn get_notebook(token: &str, notebook_id: &str) -> Result<Notebook> {
    let notebooks = list_notebooks(token).await?;
    notebooks
        .into_iter()
        .find(|n| n.id == notebook_id)
        .ok_or_else(|| anyhow::anyhow!("Notebook not found"))
}

pub async fn update_notebook(token: &str, notebook_id: &str, name: &str) -> Result<()> {
    notebooks_api::update_notebook(token, notebook_id, name).await
}

pub async fn delete_notebook(token: &str, notebook_id: &str) -> Result<()> {
    notebooks_api::delete_notebook(token, notebook_id).await
}
