from datetime import datetime
from decimal import Decimal
from typing import Optional, Literal
from uuid import UUID
from pydantic import BaseModel, Field


class StepCommand(BaseModel):
    """A command that can be run as part of a step."""
    label: str
    command: str
    command_type: Optional[str] = None  # e.g., 'powershell', 'cmd', 'bash'


class StepContent(BaseModel):
    """Content structure for step library entries (stored as JSONB)."""
    instructions: str = Field(..., min_length=1)
    help_text: Optional[str] = None
    commands: Optional[list[StepCommand]] = None
    group_label: Optional[str] = None  # Section header this step belongs to (for flow-synced steps)


# Base schemas
class StepLibraryBase(BaseModel):
    title: str = Field(..., min_length=1, max_length=255)
    step_type: Literal['decision', 'action', 'solution']
    content: StepContent
    category_id: Optional[UUID] = None
    tags: list[str] = Field(default_factory=list)
    visibility: Literal['private', 'team', 'public'] = 'private'


class StepLibraryCreate(StepLibraryBase):
    account_id: Optional[UUID] = None


class StepLibraryUpdate(BaseModel):
    title: Optional[str] = Field(None, min_length=1, max_length=255)
    step_type: Optional[Literal['decision', 'action', 'solution']] = None
    content: Optional[StepContent] = None
    category_id: Optional[UUID] = None
    tags: Optional[list[str]] = None
    visibility: Optional[Literal['private', 'team', 'public']] = None


class StepLibraryResponse(StepLibraryBase):
    id: UUID
    created_by: UUID
    account_id: Optional[UUID] = None
    usage_count: int
    rating_average: Decimal
    rating_count: int
    helpful_yes: int
    helpful_no: int
    is_featured: bool
    is_verified: bool
    is_active: bool
    created_at: datetime
    updated_at: datetime
    # Computed fields (populated by API)
    category_name: Optional[str] = None
    author_name: Optional[str] = None
    is_flow_synced: bool = False
    source_tree_name: Optional[str] = None

    class Config:
        from_attributes = True


class StepLibraryListResponse(BaseModel):
    id: UUID
    title: str
    step_type: str
    visibility: str
    category_id: Optional[UUID] = None
    category_name: Optional[str] = None
    tags: list[str]
    usage_count: int
    rating_average: Decimal
    rating_count: int
    is_featured: bool
    created_by: UUID
    author_name: Optional[str] = None
    created_at: datetime
    is_flow_synced: bool = False
    source_tree_name: Optional[str] = None

    class Config:
        from_attributes = True


# Rating schemas
class StepRatingBase(BaseModel):
    rating: int = Field(..., ge=1, le=5)
    was_helpful: Optional[bool] = None
    review_text: Optional[str] = Field(None, max_length=500)


class StepRatingCreate(StepRatingBase):
    session_id: Optional[UUID] = None  # For verified use tracking


class StepRatingUpdate(BaseModel):
    rating: Optional[int] = Field(None, ge=1, le=5)
    was_helpful: Optional[bool] = None
    review_text: Optional[str] = Field(None, max_length=500)


class StepRatingResponse(StepRatingBase):
    id: UUID
    step_id: UUID
    user_id: UUID
    is_verified_use: bool
    session_id: Optional[UUID] = None
    is_visible: bool
    created_at: datetime
    updated_at: datetime
    # Computed
    user_name: Optional[str] = None

    class Config:
        from_attributes = True


# Search and filter schemas
class StepSearchParams(BaseModel):
    q: Optional[str] = None  # Full-text search query
    category_id: Optional[UUID] = None
    tags: Optional[list[str]] = None
    min_rating: Optional[float] = Field(None, ge=0, le=5)
    step_type: Optional[Literal['decision', 'action', 'solution']] = None
    visibility: Optional[Literal['private', 'team', 'public']] = None
    sort_by: Literal['recent', 'popular', 'highest_rated', 'most_used'] = 'recent'
    limit: int = Field(20, ge=1, le=100)
    offset: int = Field(0, ge=0)


class PopularTagResponse(BaseModel):
    tag: str
    count: int
