use anyhow::Result;

use crate::api::PlaneApiClient;
use crate::config::{ProjectScope, resolve_plane_session};
use crate::terminal_ui::OutputFormat;

use super::ls::WorkItemListRenderer;

/// Searches work item titles by substring match across all items in the active project.
/// Fetches all work items client-side and filters by case-insensitive title containment,
/// then renders matching results in the same table/json/csv format as `plane ls`.
#[derive(clap::Args)]
pub struct SearchWorkItemsArgs {
    /// The search query text to match against work item titles (case-insensitive)
    search_text: String,
    /// Project slug to query (overrides the configured default project)
    #[arg(long)]
    project: Option<String>,
    /// Output format: table (default for TTY), json (default for pipes), csv
    #[arg(long)]
    format: Option<String>,
}

/// Execution logic for the `plane search` subcommand
impl SearchWorkItemsArgs {
    /// Fetches all work items from the target project, filters by title substring match,
    /// and renders results using the shared work item list renderer
    pub async fn execute(self) -> Result<()> {
        let plane_session = resolve_plane_session()?;
        let api_client = PlaneApiClient::try_new(plane_session)?;

        let target_project_slug = match self.project {
            Option::Some(ref explicit_project) => explicit_project.parse()?,
            Option::None => match api_client.project_scope() {
                ProjectScope::Scoped(default_project) => default_project.as_str().parse()?,
                ProjectScope::ExplicitOnly => {
                    anyhow::bail!(
                        "no default project configured — pass --project or run: \
                         plane config --project <slug>"
                    );
                }
            },
        };

        let resolved_project = api_client
            .find_project_by_slug(&target_project_slug)
            .await?;
        let project_identifier_code = resolved_project.identifier().to_owned();
        let resolved_project_id = resolved_project.id();

        let project_states = api_client.list_states(resolved_project_id).await?;
        let all_work_items = api_client.list_work_items(resolved_project_id).await?;

        let search_text_lower = self.search_text.to_lowercase();
        let matching_items: Vec<_> = all_work_items
            .iter()
            .filter(|work_item| {
                work_item
                    .title()
                    .as_str()
                    .to_lowercase()
                    .contains(&search_text_lower)
            })
            .collect();

        let selected_format = match &self.format {
            Option::Some(format_text) => format_text.parse()?,
            Option::None => OutputFormat::detect_from_terminal(),
        };

        let work_item_renderer = WorkItemListRenderer {
            project_states: &project_states,
            project_identifier_code: &project_identifier_code,
        };

        match selected_format {
            OutputFormat::Table => work_item_renderer.print_table(&matching_items),
            OutputFormat::Json => work_item_renderer.print_json(&matching_items),
            OutputFormat::Csv => work_item_renderer.print_csv(&matching_items),
        }

        Ok(())
    }
}
