"""Bing news search."""

from __future__ import annotations

from time import sleep
from typing import List
from urllib.parse import urlencode

from webscout.scout import Scout
from webscout.search.results import NewsResult

from .base import BingBase


class BingNewsSearch(BingBase):
    name = "bing"
    category = "news"
    def run(self, *args, **kwargs) -> List[NewsResult]:
        keywords = args[0] if args else kwargs.get("keywords")
        region = args[1] if len(args) > 1 else kwargs.get("region", "us")
        safesearch = args[2] if len(args) > 2 else kwargs.get("safesearch", "moderate")
        max_results = args[3] if len(args) > 3 else kwargs.get("max_results", 10)

        if max_results is None:
            max_results = 10

        if not keywords:
            raise ValueError("Keywords are mandatory")

        safe_map = {
            "on": "Strict",
            "moderate": "Moderate",
            "off": "Off"
        }
        safe_map.get(safesearch.lower(), "Moderate")

        # Bing news URL
        url = f"{self.base_url}/news/infinitescrollajax"
        params = {
            'q': keywords,
            'InfiniteScroll': '1',
            'first': '1',
            'SFX': '0',
            'cc': region.lower(),
            'setlang': self.lang.split('-')[0]
        }

        results = []
        first = 1
        sfx = 0

        while len(results) < max_results:
            params['first'] = str(first)
            params['SFX'] = str(sfx)
            full_url = f"{url}?{urlencode(params)}"

            try:
                response = self.session.get(full_url, timeout=self.timeout)
                response.raise_for_status()
                html = response.text
            except Exception as e:
                raise Exception(f"Failed to fetch news: {str(e)}")

            if not html:
                break

            soup = Scout(html)
            news_items = soup.select('div.newsitem')

            for item in news_items:
                if len(results) >= max_results:
                    break

                title = item.select_one('a.title')
                snippet = item.select_one('div.snippet')
                source = item.select_one('div.source')
                date = item.select_one('span.date')

                if title:
                    news_result = NewsResult(
                        title=title.get_text(strip=True),
                        url=title.get('href', ''),
                        body=snippet.get_text(strip=True) if snippet else '',
                        source=source.get_text(strip=True) if source else '',
                        date=date.get_text(strip=True) if date else '',
                        image=""
                    )
                    results.append(news_result)

            first += 10
            sfx += 1

            if self.sleep_interval:
                sleep(self.sleep_interval)

        return results[:max_results]
