"""Class to search google using the Serper API"""

import asyncio
import json
# # from utils.logger import ServiceLogger
import logging
import os

import aiohttp
import requests
from dotenv import load_dotenv

from utils.url_parser import parsed_url

load_dotenv()
GOOGLE_SEARCH_API = os.environ["GOOGLE_SEARCH_API"]

XCM_logger = logging.getLogger()


class GoogleSearch:
    "Class to search google using the Serper API"
    type_of_search_output = {"search": "organic", "images": "images", "news": "news"}

    def __init__(self):
        "Class to search google using the Serper API"
        pass

    async def search_google(
        self,
        query,
        type_of_search,
        domain_check=False,
        domain_name_to_check: list[str] | str = None,
        num_of_results=10,
    ):
        """Get the search results from google
        query is the search query
        type_of_search is 'search' or 'images'  or 'news' for web search or image search or news search
        """
        if isinstance(domain_name_to_check, str):
            domain_name_to_check = [domain_name_to_check]

        if type_of_search not in ["search", "images", "news"]:
            raise ValueError("type_of_search must be 'search' or 'images' or 'news'")

        if type_of_search == "news":
            query = f"{query} (financial, product, company, industry)"
            num_of_results = 20

        google_search_url = f"https://google.serper.dev/{type_of_search}"
        headers = {"X-API-KEY": GOOGLE_SEARCH_API, "Content-Type": "application/json"}
        data = {"q": query, "num": num_of_results}

        async with aiohttp.ClientSession() as session:
            async with session.post(
                google_search_url, headers=headers, data=json.dumps(data)
            ) as response:
                results = await response.json()

        results = results[self.type_of_search_output[type_of_search]]

        if domain_check:
            return self.check_search_results_for_domain(results, domain_name_to_check)

        return results

    def _search_google(
        self,
        query,
        type_of_search,
        domain_check=False,
        domain_name_to_check=None,
        num_of_results=10,
    ):
        """Get the search results from google
        query is the search query
        type_of_search is 'search' or 'images' for web search or image search
        """
        if type_of_search not in ["search", "images"]:
            raise ValueError("type_of_search must be 'search' or 'images'")

        google_search_url = f"https://google.serper.dev/{type_of_search}"
        headers = {"X-API-KEY": GOOGLE_SEARCH_API, "Content-Type": "application/json"}
        data = {"q": query, "num": num_of_results}
        try:
            response = requests.post(
                google_search_url,
                headers=headers,
                data=json.dumps(data),
                timeout=10,
            )

            results = response.json()[self.type_of_search_output[type_of_search]]

            if domain_check:
                return self.check_search_results_for_domain(
                    results, domain_name_to_check
                )

            return response.json()[self.type_of_search_output[type_of_search]]

        except (TimeoutError, requests.exceptions.ConnectionError) as e:
            # print(e)
            XCM_logger.error("Error with %s: %s", google_search_url, e, exc_info=True)
            return []

    def check_search_results_for_domain(self, results, domain_name_to_check: list[str]):
        "Check the search results for the domain name"
        new_results = []
        for result in results:
            result_url = parsed_url(result["link"], False)

            if result_url.domain in domain_name_to_check:
                new_results.append(result)

        return new_results


if __name__ == "__main__":

    search = GoogleSearch()
    results = asyncio.run(search.search_google("Stairworx", "news"))

    print(results)
