"""
Search subscription - allows users to subscribe to their LDR searches for news updates.
This is the killer feature: turning searches into living news feeds.
"""

from typing import Optional, Dict, Any
from datetime import datetime, UTC
from loguru import logger

from .base_subscription import BaseSubscription
from ..core.base_card import CardSource


class SearchSubscription(BaseSubscription):
    """
    Subscription based on a user's search query.
    Transforms the original search into news-focused queries.
    """

    def __init__(
        self,
        user_id: str,
        query: str,
        source: Optional[CardSource] = None,
        refresh_interval_minutes: int = 360,  # Default 6 hours
        transform_to_news_query: bool = True,
        subscription_id: Optional[str] = None,
    ):
        """
        Initialize a search subscription.

        Args:
            user_id: ID of the user
            query: The original search query
            source: Source information (auto-created if not provided)
            refresh_interval_minutes: How often to check for news in minutes
            transform_to_news_query: Whether to add news context to query
            subscription_id: Optional ID
        """
        # Create source if not provided
        if source is None:
            source = CardSource(
                type="user_search", created_from=f"Search subscription: {query}"
            )

        super().__init__(
            user_id, source, query, refresh_interval_minutes, subscription_id
        )

        self.original_query = query
        self.transform_to_news_query = transform_to_news_query

        # Track query evolution over time
        self.query_history = [query]
        self.current_query = query

        # Set subscription type
        self.subscription_type = "search"

        # Metadata specific to search subscriptions
        self.metadata.update(
            {
                "subscription_type": "search",
                "original_query": query,
                "transform_enabled": transform_to_news_query,
            }
        )

        logger.info(f"Created search subscription for query: {query}")

    @property
    def query(self) -> str:
        """Get the original query for backward compatibility."""
        return self.original_query

    def get_subscription_type(self) -> str:
        """Return the subscription type identifier."""
        return "search_subscription"

    def generate_search_query(self) -> str:
        """
        Generate the news search query from the original search.

        Returns:
            str: The transformed search query
        """
        # Update any date placeholders with current date
        current_date = datetime.now(UTC).date().isoformat()
        updated_query = self.current_query

        # Replace YYYY-MM-DD placeholder ONLY (not all dates)
        updated_query = updated_query.replace("YYYY-MM-DD", current_date)

        if self.transform_to_news_query:
            # Add news context to the updated query
            news_query = self._transform_to_news_query(updated_query)
        else:
            news_query = updated_query

        logger.debug(f"Generated news query: {news_query}")
        return news_query

    def _transform_to_news_query(self, query: str) -> str:
        """
        Transform a regular search query into a news-focused query.

        Args:
            query: The original query

        Returns:
            str: News-focused version of the query
        """
        # Don't double-add news terms
        query_lower = query.lower()
        if any(
            term in query_lower
            for term in ["news", "latest", "recent", "today"]
        ):
            return query

        # Add temporal and news context
        # This could be more sophisticated with LLM in the future

        # Choose appropriate term based on query type
        if any(term in query_lower for term in ["how to", "tutorial", "guide"]):
            # Technical queries - look for updates
            return f"{query} latest updates developments"
        elif any(
            term in query_lower
            for term in ["vulnerability", "security", "breach"]
        ):
            # Security queries - urgent news
            return f"{query} breaking news alerts today"
        else:
            # General queries - latest news
            return f"{query} latest news developments"

    def evolve_query(self, new_terms: Optional[str] = None) -> None:
        """
        Evolve the query based on emerging trends.
        Future feature: LLM-based query evolution.

        Args:
            new_terms: New terms to incorporate
        """
        if new_terms:
            # Simple evolution for now
            evolved_query = f"{self.original_query} {new_terms}"
            self.current_query = evolved_query
            self.query_history.append(evolved_query)

            logger.info(f"Evolved search query to: {evolved_query}")

    def get_statistics(self) -> Dict[str, Any]:
        """Get statistics about this subscription."""
        stats = {
            "original_query": self.original_query,
            "current_query": self.current_query,
            "query_evolution_count": len(self.query_history) - 1,
            "total_refreshes": self.refresh_count,
            "success_rate": (
                self.refresh_count / (self.refresh_count + self.error_count)
                if (self.refresh_count + self.error_count) > 0
                else 0
            ),
        }
        return stats

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary representation."""
        data = super().to_dict()
        data.update(
            {
                "original_query": self.original_query,
                "current_query": self.current_query,
                "transform_to_news_query": self.transform_to_news_query,
                "query_history": self.query_history,
                "statistics": self.get_statistics(),
            }
        )
        return data


class SearchSubscriptionFactory:
    """
    Factory for creating search subscriptions from various sources.
    """

    @staticmethod
    def from_user_search(
        user_id: str,
        search_query: str,
        search_result_id: Optional[str] = None,
        **kwargs,
    ) -> SearchSubscription:
        """
        Create a subscription from a user's search.

        Args:
            user_id: The user who performed the search
            search_query: The original search query
            search_result_id: Optional ID of the search result
            **kwargs: Additional arguments for SearchSubscription

        Returns:
            SearchSubscription instance
        """
        source = CardSource(
            type="user_search",
            source_id=search_result_id,
            created_from=f"Your search: '{search_query}'",
            metadata={
                "search_timestamp": kwargs.get("search_timestamp"),
                "search_strategy": kwargs.get("search_strategy"),
            },
        )

        return SearchSubscription(
            user_id=user_id, query=search_query, source=source, **kwargs
        )

    @staticmethod
    def from_recommendation(
        user_id: str,
        recommended_query: str,
        recommendation_source: str,
        **kwargs,
    ) -> SearchSubscription:
        """
        Create a subscription from a system recommendation.

        Args:
            user_id: The user to create subscription for
            recommended_query: The recommended search query
            recommendation_source: What generated this recommendation
            **kwargs: Additional arguments

        Returns:
            SearchSubscription instance
        """
        source = CardSource(
            type="recommendation",
            created_from=f"Recommended based on: {recommendation_source}",
            metadata={
                "recommendation_type": kwargs.get(
                    "recommendation_type", "topic_based"
                )
            },
        )

        return SearchSubscription(
            user_id=user_id, query=recommended_query, source=source, **kwargs
        )
