from pydantic import BaseModel, Field
from datetime import datetime
from decimal import Decimal
from typing import Optional, Literal
from enum import Enum


# ============================================================
# Audit Log Schemas
# ============================================================

class AuditLogAction(str, Enum):
    DATA_WIPE = "DATA_WIPE"
    DATA_SEED = "DATA_SEED"
    SIMULATION_START = "SIMULATION_START"
    SIMULATION_STOP = "SIMULATION_STOP"
    USER_STATUS_CHANGE = "USER_STATUS_CHANGE"
    USER_BALANCE_ADJUST = "USER_BALANCE_ADJUST"
    USER_ADMIN_GRANT = "USER_ADMIN_GRANT"
    USER_ADMIN_REVOKE = "USER_ADMIN_REVOKE"
    USER_UPDATE = "USER_UPDATE"
    SETTINGS_UPDATE = "SETTINGS_UPDATE"
    EVENT_CREATE = "EVENT_CREATE"
    EVENT_UPDATE = "EVENT_UPDATE"
    EVENT_DELETE = "EVENT_DELETE"


class AuditLogResponse(BaseModel):
    id: int
    admin_id: int
    admin_username: str
    action: str
    target_type: Optional[str] = None
    target_id: Optional[int] = None
    description: str
    details: Optional[str] = None
    ip_address: Optional[str] = None
    created_at: datetime

    class Config:
        from_attributes = True


class AuditLogListResponse(BaseModel):
    logs: list[AuditLogResponse]
    total: int
    page: int
    page_size: int


# ============================================================
# Data Wiper Schemas
# ============================================================

class WipePreviewResponse(BaseModel):
    """Preview of what will be deleted in a wipe operation."""
    users_count: int
    wallets_count: int
    transactions_count: int
    bets_count: int
    spread_bets_count: int
    events_count: int
    event_comments_count: int
    match_comments_count: int
    admin_settings_preserved: bool = True
    admin_users_preserved: bool = True
    can_wipe: bool = True
    cooldown_remaining_seconds: int = 0
    last_wipe_at: Optional[datetime] = None


class WipeRequest(BaseModel):
    """Request to execute a data wipe."""
    confirmation_phrase: str = Field(..., description="Must be exactly 'CONFIRM WIPE'")
    preserve_admin_users: bool = Field(default=True, description="Keep admin users and their wallets")
    preserve_events: bool = Field(default=False, description="Keep sport events but delete bets")


class WipeResponse(BaseModel):
    """Response after a successful wipe operation."""
    success: bool
    message: str
    deleted_counts: dict[str, int]
    preserved_counts: dict[str, int]
    executed_at: datetime
    executed_by: str


# ============================================================
# Data Seeder Schemas
# ============================================================

class SeedRequest(BaseModel):
    """Request to seed the database with test data."""
    num_users: int = Field(default=10, ge=1, le=100, description="Number of users to create")
    num_events: int = Field(default=5, ge=0, le=50, description="Number of sport events to create")
    num_bets_per_event: int = Field(default=3, ge=0, le=20, description="Average bets per event")
    starting_balance: Decimal = Field(default=Decimal("1000.00"), ge=Decimal("100"), le=Decimal("10000"))
    create_admin: bool = Field(default=True, description="Create a test admin user")


class SeedResponse(BaseModel):
    """Response after seeding the database."""
    success: bool
    message: str
    created_counts: dict[str, int]
    test_admin: Optional[dict] = None  # Contains username/password if admin created


# ============================================================
# Simulation Schemas
# ============================================================

class SimulationConfig(BaseModel):
    """Configuration for activity simulation."""
    delay_seconds: float = Field(default=2.0, ge=0.5, le=30.0, description="Delay between actions")
    actions_per_iteration: int = Field(default=3, ge=1, le=10, description="Actions per iteration")
    create_users: bool = Field(default=True, description="Allow creating new users")
    create_bets: bool = Field(default=True, description="Allow creating bets")
    take_bets: bool = Field(default=True, description="Allow taking/matching bets")
    add_comments: bool = Field(default=True, description="Allow adding comments")
    cancel_bets: bool = Field(default=True, description="Allow cancelling bets")


class SimulationStatusResponse(BaseModel):
    """Response with current simulation status."""
    is_running: bool
    started_at: Optional[datetime] = None
    started_by: Optional[str] = None
    iterations_completed: int = 0
    config: Optional[SimulationConfig] = None
    last_activity: Optional[str] = None


class SimulationStartRequest(BaseModel):
    """Request to start simulation."""
    config: Optional[SimulationConfig] = None


class SimulationStartResponse(BaseModel):
    """Response after starting simulation."""
    success: bool
    message: str
    status: SimulationStatusResponse


class SimulationStopResponse(BaseModel):
    """Response after stopping simulation."""
    success: bool
    message: str
    total_iterations: int
    ran_for_seconds: float


# ============================================================
# User Management Schemas
# ============================================================

class AdminUserListItem(BaseModel):
    """User item in admin user list."""
    id: int
    email: str
    username: str
    display_name: Optional[str] = None
    is_admin: bool
    status: str
    balance: Decimal
    escrow: Decimal
    total_bets: int
    wins: int
    losses: int
    win_rate: float
    created_at: datetime

    class Config:
        from_attributes = True


class AdminUserListResponse(BaseModel):
    """Paginated list of users."""
    users: list[AdminUserListItem]
    total: int
    page: int
    page_size: int


class AdminUserDetailResponse(BaseModel):
    """Detailed user info for admin."""
    id: int
    email: str
    username: str
    display_name: Optional[str] = None
    avatar_url: Optional[str] = None
    bio: Optional[str] = None
    is_admin: bool
    status: str
    created_at: datetime
    updated_at: datetime
    # Wallet info
    balance: Decimal
    escrow: Decimal
    # Stats
    total_bets: int
    wins: int
    losses: int
    win_rate: float
    # Counts
    open_bets_count: int
    matched_bets_count: int
    transaction_count: int

    class Config:
        from_attributes = True


class AdminUserUpdateRequest(BaseModel):
    """Request to update user details."""
    display_name: Optional[str] = None
    email: Optional[str] = None
    is_admin: Optional[bool] = None


class AdminUserStatusRequest(BaseModel):
    """Request to change user status."""
    status: Literal["active", "suspended"]
    reason: Optional[str] = None


class AdminBalanceAdjustRequest(BaseModel):
    """Request to adjust user balance."""
    amount: Decimal = Field(..., description="Positive to add, negative to subtract")
    reason: str = Field(..., min_length=5, max_length=500, description="Reason for adjustment")


class AdminBalanceAdjustResponse(BaseModel):
    """Response after balance adjustment."""
    success: bool
    user_id: int
    username: str
    previous_balance: Decimal
    adjustment: Decimal
    new_balance: Decimal
    reason: str
    transaction_id: int


# ============================================================
# Admin Dashboard Stats
# ============================================================

class AdminDashboardStats(BaseModel):
    """Dashboard statistics for admin panel."""
    total_users: int
    active_users: int
    suspended_users: int
    admin_users: int
    total_events: int
    upcoming_events: int
    live_events: int
    total_bets: int
    open_bets: int
    matched_bets: int
    total_volume: Decimal
    escrow_locked: Decimal
    simulation_running: bool
