"""
Reddit Insights API Client
"""

import requests
from typing import Optional, Dict, Any, List
from .exceptions import (
    RedditInsightsError,
    AuthenticationError,
    RateLimitError,
    ValidationError,
    APIError,
)


class RedditInsightsClient:
    """
    Reddit Insights API Client.
    
    Args:
        api_key: Your Reddit Insights API key.
        base_url: Base URL for the API. Defaults to https://reddit-insights.com.
        timeout: Request timeout in seconds. Defaults to 30.
    """

    DEFAULT_BASE_URL = "https://reddit-insights.com"

    def __init__(
        self,
        api_key: str,
        base_url: str = None,
        timeout: int = 30,
    ):
        self.api_key = api_key
        self.base_url = (base_url or self.DEFAULT_BASE_URL).rstrip("/")
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
            "User-Agent": "reddit-insights-python/1.0.0",
        })

    def _request(
        self,
        method: str,
        endpoint: str,
        params: Dict[str, Any] = None,
        json_data: Dict[str, Any] = None,
    ) -> Dict[str, Any]:
        """Make an HTTP request to the API."""
        url = f"{self.base_url}{endpoint}"
        
        try:
            response = self.session.request(
                method=method,
                url=url,
                params=params,
                json=json_data,
                timeout=self.timeout,
            )
        except requests.RequestException as e:
            raise RedditInsightsError(f"Request failed: {str(e)}")

        return self._handle_response(response)

    def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
        """Handle API response and raise appropriate exceptions."""
        try:
            data = response.json()
        except ValueError:
            raise APIError(
                f"Invalid JSON response",
                status_code=response.status_code,
            )

        if response.status_code == 401:
            raise AuthenticationError(
                data.get("error", "Authentication failed"),
                status_code=401,
                response=data,
            )
        elif response.status_code == 429:
            raise RateLimitError(
                data.get("error", "Rate limit exceeded"),
                status_code=429,
                response=data,
            )
        elif response.status_code == 400:
            raise ValidationError(
                data.get("error", "Validation error"),
                status_code=400,
                response=data,
            )
        elif response.status_code >= 400:
            raise APIError(
                data.get("error", "API error"),
                status_code=response.status_code,
                response=data,
            )

        return data

    def semantic_search(
        self,
        query: str,
        limit: int = 20,
    ) -> Dict[str, Any]:
        """
        Search Reddit conversations using natural language queries.
        
        Args:
            query: Natural language search query.
            limit: Number of results to return (default: 20, max: 100).
            
        Returns:
            API response containing search results.
        """
        return self._request(
            "POST",
            "/api/v1/search/semantic",
            json_data={"query": query, "limit": limit},
        )

    def vector_search(
        self,
        query: str,
        limit: int = 30,
        start_date: str = None,
        end_date: str = None,
    ) -> Dict[str, Any]:
        """
        Perform vector similarity search on Reddit posts.
        
        Args:
            query: Search query.
            limit: Number of results to return (default: 30, max: 100).
            start_date: Start date filter (YYYY-MM-DD).
            end_date: End date filter (YYYY-MM-DD).
            
        Returns:
            API response containing search results.
        """
        data = {"query": query, "limit": limit}
        if start_date:
            data["start_date"] = start_date
        if end_date:
            data["end_date"] = end_date
        return self._request("POST", "/api/v1/search/vector", json_data=data)

    def get_trends(
        self,
        start_date: str = None,
        end_date: str = None,
        limit: int = 20,
    ) -> Dict[str, Any]:
        """
        Discover trending topics on Reddit.

        Args:
            start_date: Start date filter (YYYY-MM-DD).
            end_date: End date filter (YYYY-MM-DD).
            limit: Number of trending topics to return (default: 20, max: 100).

        Returns:
            API response containing trending topics.
        """
        data = {"limit": limit}
        if start_date:
            data["start_date"] = start_date
        if end_date:
            data["end_date"] = end_date
        return self._request("POST", "/api/v1/trends", json_data=data)

    # Sonar Management (FREE endpoints)

    def list_sonars(self) -> Dict[str, Any]:
        """
        Get all your monitoring sonars.
        This endpoint is FREE and does not count toward your API quota.

        Returns:
            API response containing list of sonars.
        """
        return self._request("GET", "/api/v1/sonars")

    def create_sonar(
        self,
        name: str,
        query: str,
        description: str = None,
        schedule: str = "daily",
        triggers: Dict[str, Any] = None,
        notify_email: bool = True,
        notify_slack: bool = False,
        slack_webhook: str = None,
    ) -> Dict[str, Any]:
        """
        Create a new monitoring sonar.
        This endpoint is FREE and does not count toward your API quota.

        Args:
            name: Name for the sonar.
            query: Search query for the sonar.
            description: Optional description.
            schedule: Execution schedule ('hourly', 'daily', 'weekly').
            triggers: Alert trigger conditions.
            notify_email: Send email notifications.
            notify_slack: Send Slack notifications.
            slack_webhook: Slack webhook URL.

        Returns:
            API response containing created sonar.
        """
        data = {
            "name": name,
            "query": query,
            "schedule": schedule,
            "notifyEmail": notify_email,
            "notifySlack": notify_slack,
        }
        if description:
            data["description"] = description
        if triggers:
            data["triggers"] = triggers
        if slack_webhook:
            data["slackWebhook"] = slack_webhook
        return self._request("POST", "/api/v1/sonars", json_data=data)

    def get_sonar_executions(
        self,
        sonar_id: str,
        limit: int = 50,
        offset: int = 0,
    ) -> Dict[str, Any]:
        """
        Get execution history for a specific sonar.
        This endpoint is FREE and does not count toward your API quota.

        Args:
            sonar_id: ID of the sonar.
            limit: Number of executions to return (default: 50).
            offset: Pagination offset (default: 0).

        Returns:
            API response containing execution history.
        """
        return self._request(
            "GET",
            f"/api/v1/sonars/{sonar_id}/executions",
            params={"limit": limit, "offset": offset},
        )

    def get_execution_detail(self, execution_id: str) -> Dict[str, Any]:
        """
        Get detailed results from a specific sonar execution.
        This endpoint is FREE and does not count toward your API quota.

        Args:
            execution_id: ID of the execution.

        Returns:
            API response containing execution details and search results.
        """
        return self._request(
            "GET",
            f"/api/v1/sonars/executions/{execution_id}",
        )

