"""Rules Engine models for vikdata API.

ALL field names use snake_case to match the backend API.

NOTE: Types like trigger_type, action_type are stored as strings.
Valid values come from database lookup tables, not hardcoded enums.
"""

from datetime import datetime
from typing import Any, Literal
from uuid import UUID

from pydantic import BaseModel, Field


class Rule(BaseModel):
    """Rule response model."""

    id: UUID = Field(..., description="Rule ID")
    tenant_id: UUID = Field(..., description="Tenant ID")
    name: str = Field(..., min_length=1, max_length=255, description="Rule name")
    description: str | None = Field(default=None, max_length=1000, description="Rule description")
    is_active: bool = Field(..., description="Whether rule is active")
    trigger_type: str = Field(..., description="Trigger type (from lookup)")
    trigger_config: dict[str, Any] = Field(default_factory=dict, description="Trigger configuration")
    conditions: dict[str, Any] = Field(default_factory=dict, description="Condition tree")
    actions: list[dict[str, Any]] = Field(default_factory=list, description="Actions to execute")
    priority: int = Field(..., ge=0, le=100, description="Rule priority (0-100)")
    cooldown_seconds: int = Field(..., ge=0, le=86400, description="Cooldown between triggers")
    last_triggered_at: datetime | None = Field(default=None, description="Last trigger timestamp")
    trigger_count: int = Field(..., ge=0, description="Total trigger count")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")


class RuleListItem(BaseModel):
    """Rule list item (subset of fields)."""

    id: UUID = Field(..., description="Rule ID")
    tenant_id: UUID = Field(..., description="Tenant ID")
    name: str = Field(..., description="Rule name")
    description: str | None = Field(default=None, description="Rule description")
    is_active: bool = Field(..., description="Whether rule is active")
    trigger_type: str = Field(..., description="Trigger type (from lookup)")
    priority: int = Field(..., description="Rule priority")
    trigger_count: int = Field(..., description="Total trigger count")
    last_triggered_at: datetime | None = Field(default=None, description="Last trigger timestamp")
    created_at: datetime = Field(..., description="Creation timestamp")


class CreateRuleRequest(BaseModel):
    """Create rule request."""

    name: str = Field(..., min_length=1, max_length=255, description="Rule name")
    description: str | None = Field(default=None, max_length=1000, description="Rule description")
    is_active: bool = Field(default=True, description="Whether rule is active")
    trigger_type: str = Field(..., description="Trigger type (from lookup)")
    trigger_config: dict[str, Any] | None = Field(default=None, description="Trigger configuration")
    conditions: dict[str, Any] | None = Field(default=None, description="Condition tree")
    actions: list[dict[str, Any]] | None = Field(default=None, description="Actions to execute")
    priority: int = Field(default=0, ge=0, le=100, description="Rule priority (0-100)")
    cooldown_seconds: int = Field(default=0, ge=0, le=86400, description="Cooldown between triggers")


class UpdateRuleRequest(BaseModel):
    """Update rule request."""

    name: str | None = Field(default=None, min_length=1, max_length=255, description="Rule name")
    description: str | None = Field(default=None, max_length=1000, description="Rule description")
    is_active: bool | None = Field(default=None, description="Whether rule is active")
    trigger_type: str | None = Field(default=None, description="Trigger type (from lookup)")
    trigger_config: dict[str, Any] | None = Field(default=None, description="Trigger configuration")
    conditions: dict[str, Any] | None = Field(default=None, description="Condition tree")
    actions: list[dict[str, Any]] | None = Field(default=None, description="Actions to execute")
    priority: int | None = Field(default=None, ge=0, le=100, description="Rule priority (0-100)")
    cooldown_seconds: int | None = Field(default=None, ge=0, le=86400, description="Cooldown")


class RuleToggleRequest(BaseModel):
    """Toggle rule active status."""

    is_active: bool = Field(..., description="New active status")


class RuleTestRequest(BaseModel):
    """Test rule against context."""

    context: dict[str, Any] = Field(..., description="Test context data")
    dry_run: bool = Field(default=True, description="Whether to execute actions")


class RuleTestResult(BaseModel):
    """Rule test result."""

    rule_id: UUID = Field(..., description="Rule ID")
    conditions_matched: bool = Field(..., description="Whether conditions matched")
    evaluation_details: dict[str, Any] = Field(..., description="Evaluation details")
    actions_would_execute: list[dict[str, Any]] = Field(..., description="Actions that would execute")
    actions_executed: list[dict[str, Any]] = Field(..., description="Actions that were executed")


class ManualTriggerResult(BaseModel):
    """Manual trigger result."""

    rule_id: UUID = Field(..., description="Rule ID")
    rule_name: str = Field(..., description="Rule name")
    triggered: bool = Field(..., description="Whether rule was triggered")
    reason: str | None = Field(default=None, description="Reason if not triggered")
    cooldown_remaining_seconds: int | None = Field(default=None, description="Remaining cooldown")
    actions_executed: list[dict[str, Any]] | None = Field(default=None, description="Executed actions")
    triggered_at: datetime | None = Field(default=None, description="Trigger timestamp")


class RuleListParams(BaseModel):
    """Query parameters for listing rules."""

    page: int | None = Field(default=1, ge=1, description="Page number")
    per_page: int | None = Field(default=20, ge=1, le=100, description="Items per page")
    is_active: bool | None = Field(default=None, description="Filter by active status")
    trigger_type: str | None = Field(default=None, description="Filter by trigger type (from lookup)")
    search: str | None = Field(default=None, description="Search by name or description")
    sort: str | None = Field(default=None, description="Sort field")
    order: Literal["asc", "desc"] | None = Field(default=None, description="Sort order")
