from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field


class ControlPoint(BaseModel):
    """A control point for a drawing shape.

    Control points define the position and properties of a shape.
    Different shapes have different numbers of control points.
    """
    time: int = Field(..., description="Unix timestamp in seconds")
    price: float = Field(..., description="Price level")
    # Optional channel for multi-point shapes (e.g., parallel channels)
    channel: Optional[str] = Field(default=None, description="Channel identifier for multi-point shapes")


class Shape(BaseModel):
    """A TradingView drawing shape/study.

    Represents any drawing the user creates on the chart (trendlines,
    horizontal lines, rectangles, Fibonacci retracements, etc.)
    """
    id: str = Field(..., description="Unique identifier for the shape")
    type: str = Field(..., description="Shape type (e.g., 'trendline', 'horizontal_line', 'rectangle', 'fibonacci')")
    points: List[ControlPoint] = Field(default_factory=list, description="Control points that define the shape")

    # Visual properties
    color: Optional[str] = Field(default=None, description="Shape color (hex or color name)")
    line_width: Optional[int] = Field(default=1, description="Line width in pixels")
    line_style: Optional[str] = Field(default="solid", description="Line style: 'solid', 'dashed', 'dotted'")

    # Shape-specific properties stored as flexible dict
    properties: Dict[str, Any] = Field(default_factory=dict, description="Additional shape-specific properties")

    # Metadata
    symbol: Optional[str] = Field(default=None, description="Symbol this shape is drawn on")
    created_at: Optional[int] = Field(default=None, description="Creation timestamp (Unix seconds)")
    modified_at: Optional[int] = Field(default=None, description="Last modification timestamp (Unix seconds)")
    original_id: Optional[str] = Field(default=None, description="Original ID from backend/agent before TradingView assigns its own ID")


class ShapeCollection(BaseModel):
    """Collection of all shapes/drawings on the chart."""
    shapes: Dict[str, Shape] = Field(default_factory=dict, description="Dictionary of shapes keyed by ID")
