"""
Safety Filter CRUD API Client

Safety filters, groups, and group stopwords management.
"""

from typing import Dict, Any, Optional, List, Union

from requests.exceptions import RequestException

from adxp_sdk.auth import BaseCredentials
from adxp_sdk.base import BaseClient

class SafetyFilterClient(BaseClient):
    """
    Safety Filter Client for managing safety filters, groups, and stopwords.

    This client provides CRUD functionality for:
    - safety-filters: individual safety filter (stopword) management
    - safety-filter-groups: group management
    - safety-filter-group-stopwords: stopwords within groups

    How to use:
        >>> from adxp_sdk.auth import TokenCredentials
        >>> from adxp_sdk.safetyfilters import SafetyFilterClient
        >>>
        >>> credentials = TokenCredentials(
        ...     base_url="https://aip.sktai.io",
        ...     access_token="...",
        ...     refresh_token="..."
        ... )
        >>> client = SafetyFilterClient(credentials)
        >>>
        >>> # List groups
        >>> groups = client.get_groups(page=1, size=10)
        >>>
        >>> # Create group
        >>> group = client.create_group({"name": "my-group"})
        >>>
        >>> # Create safety filter
        >>> sf = client.create_safety_filter({"stopword": "keyword", "group_id": "..."})
    """

    def __init__(self, credentials: BaseCredentials):
        """
        Initialize the SafetyFilterClient.

        Args:
            credentials: Authentication credentials (BaseCredentials)
        """
        super().__init__(credentials)

    def _build_endpoint(self, path: str = "") -> str:
        """Build endpoint path for safety filter API."""
        base = "api/v1/safety-filters"
        if not path or not path.strip():
            return base
        return f"{base}/{path.lstrip('/')}"

    # ====================================================================
    # safety-filters
    # ====================================================================

    def create_safety_filter(
        self, data: Union[Dict[str, Any], Any]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Create a new safety filter (POST /api/v1/safety-filters).

        Args:
            data: Safety filter data (stopword, group_id, label, etc.)

        Returns:
            Created safety filter info
        """
        payload = data if isinstance(data, dict) else data.model_dump(exclude_none=True)
        return self._make_request("POST", self._build_endpoint(), json_data=payload)

    def get_safety_filters(
        self,
        page: int = 1,
        size: int = 10,
        sort: Optional[str] = None,
        filter: Optional[str] = None,
        search: Optional[str] = None,
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        List safety filters (GET /api/v1/safety-filters).

        Args:
            page: Page number
            size: Page size (-1 for all)
            sort: Sort condition (e.g., stopword,asc | updated_at,desc)
            filter: Filter condition (e.g., label:unsafe_user_defined)
            search: Search by stopword (partial match)

        Returns:
            List of safety filters with pagination
        """
        params: Dict[str, Any] = {"page": page, "size": size}
        if sort:
            params["sort"] = sort
        if filter:
            params["filter"] = filter
        if search:
            params["search"] = search
        return self._make_request("GET", self._build_endpoint(), params=params)

    def get_safety_filter(
        self, safety_filter_id: str
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Get a safety filter by ID (GET /api/v1/safety-filters/{safety_filter_id}).

        Args:
            safety_filter_id: Safety filter UUID

        Returns:
            Safety filter detail
        """
        return self._make_request("GET", self._build_endpoint(safety_filter_id))

    def update_safety_filter(
        self, safety_filter_id: str, data: Union[Dict[str, Any], Any]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Update a safety filter (PUT /api/v1/safety-filters/{safety_filter_id}).

        Args:
            safety_filter_id: Safety filter UUID
            data: Update data (stopword, group_id, label, etc.)

        Returns:
            Updated safety filter
        """
        payload = data if isinstance(data, dict) else data.model_dump(exclude_none=True)
        return self._make_request(
            "PUT", self._build_endpoint(safety_filter_id), json_data=payload
        )

    def delete_safety_filter(
        self, safety_filter_id: str
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Delete a safety filter (DELETE /api/v1/safety-filters/{safety_filter_id}).

        Args:
            safety_filter_id: Safety filter UUID

        Returns:
            Delete result (204 No Content)
        """
        return self._make_request("DELETE", self._build_endpoint(safety_filter_id))

    def check_safe(
        self,
        utterance: str,
        method: Optional[List[str]] = None,
        allowed_unsafe_labels: Optional[List[str]] = None,
        type: Optional[str] = None,
        filter_list: Optional[List[str]] = None,
        project_id: Optional[str] = None,
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Check if utterance is safe (POST /api/v1/safety-filters/safe).

        Args:
            utterance: Text to check
            method: Optional method list
            allowed_unsafe_labels: Optional allowed unsafe labels
            type: Optional type (input|output)
            filter_list: Optional list of group IDs to filter
            project_id: Optional project ID

        Returns:
            Safety check result (is_safe, redirection_message, stopword, etc.)
        """
        payload: Dict[str, Any] = {"utterance": utterance}
        if method is not None:
            payload["method"] = method
        if allowed_unsafe_labels is not None:
            payload["allowed_unsafe_labels"] = allowed_unsafe_labels
        if type is not None:
            payload["type"] = type
        if filter_list is not None:
            payload["filter_list"] = filter_list

        params = {}
        if project_id is not None:
            params["project_id"] = project_id

        return self._make_request(
            "POST",
            self._build_endpoint("safe"),
            json_data=payload,
            params=params if params else None,
        )

    # ====================================================================
    # safety-filter-groups
    # ====================================================================

    def get_groups(
        self,
        page: int = 1,
        size: int = 10,
        sort: Optional[str] = None,
        filter: Optional[str] = None,
        search: Optional[str] = None,
        group_id: Optional[str] = None,
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        List safety filter groups (GET /api/v1/safety-filters/groups).

        Args:
            page: Page number
            size: Page size (-1 for all)
            sort: Sort condition (e.g., group_name,asc | updated_at,desc)
            filter: Filter condition
            search: Search by group name
            group_id: Filter by specific group ID

        Returns:
            List of groups with pagination
        """
        params: Dict[str, Any] = {"page": page, "size": size}
        if sort:
            params["sort"] = sort
        if filter:
            params["filter"] = filter
        if search:
            params["search"] = search
        if group_id:
            params["group_id"] = group_id
        return self._make_request("GET", self._build_endpoint("groups"), params=params)

    def get_group(self, group_id: str) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Get a group by ID (GET /api/v1/safety-filters/groups/{group_id}).

        Args:
            group_id: Group UUID

        Returns:
            Group detail
        """
        return self._make_request("GET", self._build_endpoint(f"groups/{group_id}"))

    def create_group(
        self, data: Union[Dict[str, Any], Any]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Create a new safety filter group (POST /api/v1/safety-filters/groups).

        Args:
            data: Group data (name, policy, etc.)

        Returns:
            Created group info
        """
        payload = data if isinstance(data, dict) else data.model_dump(exclude_none=True)
        return self._make_request("POST", self._build_endpoint("groups"), json_data=payload)

    def update_group(
        self, group_id: str, data: Union[Dict[str, Any], Any]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Update a group (PUT /api/v1/safety-filters/groups/{group_id}).

        Args:
            group_id: Group UUID
            data: Update data (name, etc.)

        Returns:
            Updated group
        """
        payload = data if isinstance(data, dict) else data.model_dump(exclude_none=True)
        return self._make_request(
            "PUT", self._build_endpoint(f"groups/{group_id}"), json_data=payload
        )

    def delete_group(
        self, group_id: str
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Delete a group (DELETE /api/v1/safety-filters/groups/{group_id}).

        Args:
            group_id: Group UUID

        Returns:
            Delete result (204 No Content)
        """
        return self._make_request("DELETE", self._build_endpoint(f"groups/{group_id}"))

    # ====================================================================
    # safety-filter-group-stopwords
    # ====================================================================

    def get_groups_stopwords(
        self,
        page: int = 1,
        size: int = 10,
        sort: Optional[str] = None,
        filter: Optional[str] = None,
        search: Optional[str] = None,
        group_id: Optional[str] = None,
        fetch_mode: Optional[str] = None,
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Get stopwords grouped by group (GET /api/v1/safety-filters/groups/stopwords).

        Args:
            page: Page number
            size: Page size (-1 for all)
            sort: Sort condition
            filter: Filter condition
            search: Search by group name or stopwords
            group_id: Filter by specific group ID
            fetch_mode: Fetch mode (default|lazy)

        Returns:
            List of groups with stopwords
        """
        params: Dict[str, Any] = {"page": page, "size": size}
        if sort:
            params["sort"] = sort
        if filter:
            params["filter"] = filter
        if search:
            params["search"] = search
        if group_id:
            params["group_id"] = group_id
        if fetch_mode:
            params["fetch_mode"] = fetch_mode
        return self._make_request(
            "GET", self._build_endpoint("groups/stopwords"), params=params
        )

    def put_group_stopwords(
        self, group_id: str, stopwords: List[str]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Replace all stopwords in a group (PUT /api/v1/safety-filters/groups/{group_id}/stopwords).

        Args:
            group_id: Group UUID
            stopwords: List of stopwords (replaces all existing)

        Returns:
            Update result
        """
        return self._make_request(
            "PUT",
            self._build_endpoint(f"groups/{group_id}/stopwords"),
            json_data={"stopwords": stopwords},
        )

    def post_group_stopwords(
        self, group_id: str, stopwords: List[str]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Append stopwords to a group (POST /api/v1/safety-filters/groups/{group_id}/stopwords).

        Args:
            group_id: Group UUID
            stopwords: List of stopwords to append

        Returns:
            Update result
        """
        return self._make_request(
            "POST",
            self._build_endpoint(f"groups/{group_id}/stopwords"),
            json_data={"stopwords": stopwords},
        )

    def delete_group_stopwords(
        self, group_id: str, stopwords: List[str]
    ) -> Union[Dict[str, Any], List[Any], Any]:
        """
        Delete stopwords from a group (DELETE /api/v1/safety-filters/groups/{group_id}/stopwords).

        Args:
            group_id: Group UUID
            stopwords: List of stopwords to delete

        Returns:
            Delete result
        """
        return self._make_request(
            "DELETE",
            self._build_endpoint(f"groups/{group_id}/stopwords"),
            json_data={"stopwords": stopwords},
        )
