"""Evaboot MCP Server — expose the Evaboot public API as MCP tools."""

import json

from mcp.server.fastmcp import FastMCP

from evaboot_mcp.client import EvabootClient

mcp = FastMCP(
    "evaboot",
    instructions=(
        "Evaboot helps you find professional emails, validate email addresses, "
        "and extract LinkedIn Sales Navigator data. Use check_quota first to see "
        "available credits before running operations that cost credits."
    ),
)


def _client() -> EvabootClient:
    return EvabootClient()


def _fmt(data: dict) -> str:
    return json.dumps(data, indent=2, default=str)


# ---------------------------------------------------------------------------
# Search Builder
# ---------------------------------------------------------------------------


@mcp.tool()
async def generate_search_url(
    description: str,
    search_type: str = "LEAD",
) -> str:
    """Generate a LinkedIn Sales Navigator search URL from a natural language description.

    Use this when a user describes the kind of leads or companies they want to find.
    Returns a valid Sales Nav URL and a summary of the filters chosen.
    After generating the URL, use extract_from_url to run the extraction.

    Costs no credits but limited to 100 requests/day.

    Args:
        description: Natural language description of target audience (e.g. "CTOs at SaaS companies in the US with 50-200 employees").
        search_type: "LEAD" for people search, "ACCOUNT" for company search.
    """
    return _fmt(await _client().generate_search_url(description, search_type))


# ---------------------------------------------------------------------------
# Quota
# ---------------------------------------------------------------------------


@mcp.tool()
async def check_quota() -> str:
    """Check your Evaboot account quota: daily extraction limit, usage, remaining credits, and linked Sales Navigator accounts."""
    return _fmt(await _client().get_quota())


# ---------------------------------------------------------------------------
# Email Finder
# ---------------------------------------------------------------------------


@mcp.tool()
async def find_email(
    first_name: str,
    last_name: str,
    company_name: str = "",
    company_domain: str = "",
) -> str:
    """Find a professional email address for one person. Provide either company_name or company_domain (or both). Costs 1 credit.

    Args:
        first_name: Person's first name.
        last_name: Person's last name.
        company_name: Company name (required if company_domain not given).
        company_domain: Company website domain (required if company_name not given).
    """
    return _fmt(
        await _client().find_email_single(
            first_name, last_name, company_name, company_domain
        )
    )


@mcp.tool()
async def find_emails_bulk(
    prospects: list[dict],
    job_name: str,
    webhook_url: str | None = None,
) -> str:
    """Start an async bulk email-finder job. Returns a job_id to poll with get_email_finder_job. Costs 1 credit per prospect.

    Args:
        prospects: List of objects with keys: first_name, last_name, and company_name or company_domain.
        job_name: A name for this job.
        webhook_url: Optional URL to receive a POST when the job completes.
    """
    return _fmt(await _client().find_emails_bulk(prospects, job_name, webhook_url))


@mcp.tool()
async def list_email_finder_jobs() -> str:
    """List your completed email-finder jobs."""
    return _fmt(await _client().list_email_finder_jobs())


@mcp.tool()
async def get_email_finder_job(job_id: str) -> str:
    """Get results of an email-finder job. Returns 202-style data while processing, full results when complete.

    Args:
        job_id: The job ID returned when the job was created.
    """
    return _fmt(await _client().get_email_finder_job(job_id))


# ---------------------------------------------------------------------------
# Email Validation
# ---------------------------------------------------------------------------


@mcp.tool()
async def validate_email(email: str) -> str:
    """Validate a single email address. Returns validity status (safe, riskier, etc.). Costs 0.5 credits.

    Args:
        email: The email address to validate.
    """
    return _fmt(await _client().validate_email_single(email))


@mcp.tool()
async def validate_emails_bulk(
    emails: list[str],
    job_name: str,
    webhook_url: str | None = None,
) -> str:
    """Start an async bulk email-validation job. Returns a job_id to poll with get_email_validation_job. Costs 0.5 credits per email.

    Args:
        emails: List of email addresses to validate.
        job_name: A name for this job.
        webhook_url: Optional URL to receive a POST when the job completes.
    """
    return _fmt(await _client().validate_emails_bulk(emails, job_name, webhook_url))


@mcp.tool()
async def list_email_validation_jobs() -> str:
    """List your completed email-validation jobs."""
    return _fmt(await _client().list_email_validation_jobs())


@mcp.tool()
async def get_email_validation_job(job_id: str) -> str:
    """Get results of an email-validation job. Returns 202-style data while processing, full results when complete.

    Args:
        job_id: The job ID returned when the job was created.
    """
    return _fmt(await _client().get_email_validation_job(job_id))


# ---------------------------------------------------------------------------
# LinkedIn Extractions
# ---------------------------------------------------------------------------


@mcp.tool()
async def extract_from_url(
    linkedin_url: str,
    search_name: str,
    enrich_email: str = "none",
    webhook_url: str | None = None,
) -> str:
    """Start a LinkedIn extraction from a Sales Navigator search or list URL (async). Returns an extraction_id.

    Args:
        linkedin_url: Full Sales Navigator search or list URL.
        search_name: A name for this extraction.
        enrich_email: Email enrichment: "none", "matching", or "all".
        webhook_url: Optional URL to receive a POST when extraction completes.
    """
    return _fmt(
        await _client().extract_from_url(
            linkedin_url, search_name, enrich_email, webhook_url
        )
    )


@mcp.tool()
async def extract_profiles(
    profile_ids: list[str],
    search_name: str,
    enrich_email: str = "none",
    webhook_url: str | None = None,
) -> str:
    """Start a LinkedIn extraction for specific profile URLs or IDs (async). Returns an extraction_id.

    Args:
        profile_ids: List of LinkedIn Sales Navigator profile URLs or IDs.
        search_name: A name for this extraction.
        enrich_email: Email enrichment: "none", "matching", or "all".
        webhook_url: Optional URL to receive a POST when extraction completes.
    """
    return _fmt(
        await _client().extract_profiles(
            profile_ids, search_name, enrich_email, webhook_url
        )
    )


@mcp.tool()
async def extract_single_profile(
    profile_id: str,
    enrich_email: str = "none",
) -> str:
    """Extract a single LinkedIn profile synchronously. Returns the prospect data immediately.

    Args:
        profile_id: LinkedIn Sales Navigator profile URL or ID.
        enrich_email: Email enrichment: "none", "matching", or "all".
    """
    return _fmt(await _client().extract_single_profile(profile_id, enrich_email))


@mcp.tool()
async def list_extractions() -> str:
    """List your completed LinkedIn extractions."""
    return _fmt(await _client().list_extractions())


@mcp.tool()
async def get_extraction(extraction_id: str) -> str:
    """Get results of a LinkedIn extraction. Returns 202-style data while processing, full prospect data when complete.

    Args:
        extraction_id: The extraction ID returned when the extraction was created.
    """
    return _fmt(await _client().get_extraction(extraction_id))


def main():
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()
