"""Rules Engine API endpoints."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any
from uuid import UUID

from vikdata.models.common import PaginatedResponse
from vikdata.models.rule import (
    Rule,
    RuleListItem,
    CreateRuleRequest,
    UpdateRuleRequest,
    RuleToggleRequest,
    RuleTestRequest,
    RuleTestResult,
    ManualTriggerResult,
)

if TYPE_CHECKING:
    from vikdata.client import VikdataClient


class RulesAPI:
    """Rules Engine API endpoints.

    Handles rule CRUD operations, testing, and manual triggering.
    """

    def __init__(self, client: "VikdataClient") -> None:
        self._client = client

    async def list(
        self,
        *,
        page: int | None = None,
        per_page: int | None = None,
        is_active: bool | None = None,
        trigger_type: str | None = None,
        search: str | None = None,
        sort: str | None = None,
        order: str | None = None,
    ) -> PaginatedResponse[RuleListItem]:
        """List rules for the current tenant.

        Args:
            page: Page number (default: 1)
            per_page: Items per page (default: 20, max: 100)
            is_active: Filter by active status
            trigger_type: Filter by trigger type (from lookup)
            search: Search by name or description
            sort: Sort field
            order: Sort order ('asc' or 'desc')

        Returns:
            Paginated list of rules
        """
        params = {
            "page": page,
            "per_page": per_page,
            "is_active": is_active,
            "trigger_type": trigger_type,
            "search": search,
            "sort": sort,
            "order": order,
        }
        params = {k: v for k, v in params.items() if v is not None}

        return await self._client.request(
            "GET",
            "/api/v1/rules",
            params=params,
            response_model=PaginatedResponse[RuleListItem],
        )

    async def get(self, rule_id: UUID) -> Rule:
        """Get a rule by ID.

        Args:
            rule_id: Rule ID

        Returns:
            Rule details
        """
        return await self._client.request(
            "GET",
            f"/api/v1/rules/{rule_id}",
            response_model=Rule,
        )

    async def create(self, data: CreateRuleRequest) -> Rule:
        """Create a new rule.

        Args:
            data: Rule creation data

        Returns:
            Created rule
        """
        return await self._client.request(
            "POST",
            "/api/v1/rules",
            json=data,
            response_model=Rule,
        )

    async def update(self, rule_id: UUID, data: UpdateRuleRequest) -> Rule:
        """Update a rule.

        Args:
            rule_id: Rule ID
            data: Rule update data

        Returns:
            Updated rule
        """
        return await self._client.request(
            "PATCH",
            f"/api/v1/rules/{rule_id}",
            json=data,
            response_model=Rule,
        )

    async def delete(self, rule_id: UUID) -> None:
        """Delete (soft delete) a rule.

        Args:
            rule_id: Rule ID
        """
        await self._client.request(
            "DELETE",
            f"/api/v1/rules/{rule_id}",
        )

    async def toggle(self, rule_id: UUID, data: RuleToggleRequest) -> Rule:
        """Toggle a rule's active state.

        Args:
            rule_id: Rule ID
            data: Toggle request with new active state

        Returns:
            Updated rule
        """
        return await self._client.request(
            "POST",
            f"/api/v1/rules/{rule_id}/toggle",
            json=data,
            response_model=Rule,
        )

    async def test(self, rule_id: UUID, data: RuleTestRequest) -> RuleTestResult:
        """Test a rule with sample context data.

        Args:
            rule_id: Rule ID
            data: Test request with context data and dry_run flag

        Returns:
            Test result with evaluation details
        """
        return await self._client.request(
            "POST",
            f"/api/v1/rules/{rule_id}/test",
            json=data,
            response_model=RuleTestResult,
        )

    async def trigger(
        self,
        rule_id: UUID,
        context: dict[str, Any] | None = None,
    ) -> ManualTriggerResult:
        """Manually trigger a rule.

        Args:
            rule_id: Rule ID
            context: Optional context data for the trigger

        Returns:
            Trigger result with execution details
        """
        return await self._client.request(
            "POST",
            f"/api/v1/rules/{rule_id}/trigger",
            json=context,
            response_model=ManualTriggerResult,
        )
