use super::{PgxGetArgs, PgxSearchArgs};
use crate::cli::CommandOutcome;

pub(super) fn validate_search_args(args: &PgxSearchArgs) -> Result<(), crate::error::BioMcpError> {
    if args.limit == 0 || args.limit > 50 {
        return Err(crate::error::BioMcpError::InvalidArgument(
            "--limit must be between 1 and 50".into(),
        ));
    }
    Ok(())
}

pub(in crate::cli) async fn handle_get(
    args: PgxGetArgs,
    json: bool,
) -> anyhow::Result<CommandOutcome> {
    let (sections, json_override) = super::super::extract_json_from_sections(&args.sections);
    let json_output = json || json_override;
    let pgx = crate::entities::pgx::get(&args.query, &sections).await?;
    let text = if json_output {
        crate::render::json::to_entity_json(
            &pgx,
            crate::render::markdown::pgx_evidence_urls(&pgx),
            crate::render::markdown::related_pgx(&pgx),
            crate::render::provenance::pgx_section_sources(&pgx),
        )?
    } else {
        crate::render::markdown::pgx_markdown(&pgx, &sections)?
    };
    Ok(CommandOutcome::stdout(text))
}

pub(in crate::cli) async fn handle_search(
    args: PgxSearchArgs,
    json: bool,
) -> anyhow::Result<CommandOutcome> {
    validate_search_args(&args)?;
    let gene = super::super::resolve_query_input(args.gene, args.positional_query, "--gene")?;
    let filters = crate::entities::pgx::PgxSearchFilters {
        gene,
        drug: args.drug,
        cpic_level: args.cpic_level,
        pgx_testing: args.pgx_testing,
        evidence: args.evidence,
    };
    let mut query_summary = crate::entities::pgx::search_query_summary(&filters);
    if args.offset > 0 {
        query_summary = format!("{query_summary}, offset={}", args.offset);
    }
    let page = crate::entities::pgx::search_page(&filters, args.limit, args.offset).await?;
    let results = page.results;
    let pagination =
        super::super::PaginationMeta::offset(args.offset, args.limit, results.len(), page.total);
    let text = if json {
        let next_commands = crate::render::markdown::search_next_commands_pgx(
            &results,
            filters.gene.as_deref(),
            filters.drug.as_deref(),
        );
        super::super::search_json_with_meta(results, pagination, next_commands)?
    } else {
        let footer = super::super::pagination_footer_offset(&pagination);
        crate::render::markdown::pgx_search_markdown_with_footer(&query_summary, &results, &footer)?
    };
    Ok(CommandOutcome::stdout(text))
}
