import os
import re
from typing import Any, Optional, Union, List

from crewai.tools import BaseTool, EnvVar


class SerpApiBaseTool(BaseTool):
    """Base class for SerpApi functionality with shared capabilities."""

    package_dependencies: List[str] = ["serpapi"]
    env_vars: List[EnvVar] = [
        EnvVar(name="SERPAPI_API_KEY", description="API key for SerpApi searches", required=True),
    ]

    client: Optional[Any] = None

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        try:
            from serpapi import Client  # type: ignore
        except ImportError:
            import click

            if click.confirm(
                "You are missing the 'serpapi' package. Would you like to install it?"
            ):
                import subprocess

                subprocess.run(["uv", "add", "serpapi"], check=True)
                from serpapi import Client
            else:
                raise ImportError(
                    "`serpapi` package not found, please install with `uv add serpapi`"
                )
        api_key = os.getenv("SERPAPI_API_KEY")
        if not api_key:
            raise ValueError(
                "Missing API key, you can get the key from https://serpapi.com/manage-api-key"
            )
        self.client = Client(api_key=api_key)

    def _omit_fields(self, data: Union[dict, list], omit_patterns: list[str]) -> None:
        if isinstance(data, dict):
            for field in list(data.keys()):
                if any(re.compile(p).match(field) for p in omit_patterns):
                    data.pop(field, None)
                else:
                    if isinstance(data[field], (dict, list)):
                        self._omit_fields(data[field], omit_patterns)
        elif isinstance(data, list):
            for item in data:
                self._omit_fields(item, omit_patterns)
