"""
Dashboard and Widget contracts for the pipeline system.

These TypedDicts define the data structures for dynamic dashboard configuration,
allowing pipelines to declare their dashboard widgets which the frontend renders.
"""

from __future__ import annotations

from typing import Any, Literal, TypedDict


# =============================================================================
# Widget Types
# =============================================================================

WidgetType = Literal[
    "stat_card",      # KPI stat card with value and optional trend
    "line_chart",     # Time series line chart
    "bar_chart",      # Bar chart (horizontal or vertical)
    "pie_chart",      # Pie/donut chart
    "table",          # Data table with columns
    "heatmap",        # Heatmap grid visualization
    "area_chart",     # Stacked area chart
    "gauge",          # Gauge/meter visualization
]


# =============================================================================
# Widget Configuration
# =============================================================================


class GridPosition(TypedDict):
    """Grid position for a widget in the dashboard layout."""

    x: int           # Column position (0-based)
    y: int           # Row position (0-based)
    w: int           # Width in grid units
    h: int           # Height in grid units


class StatCardConfig(TypedDict, total=False):
    """Configuration specific to stat card widgets."""

    value_key: str           # Key in data for the main value
    label: str               # Label to display
    format: str              # Format string (e.g., "{value:,}", "{value:.1%}")
    trend_key: str | None    # Key for trend value (optional)
    trend_format: str | None # Format for trend (e.g., "+{value:.1%}")
    icon: str | None         # Icon name (optional)
    color: str | None        # Color theme (e.g., "blue", "green", "red")


class ChartAxisConfig(TypedDict, total=False):
    """Configuration for chart axes."""

    key: str                 # Data key for this axis
    label: str               # Axis label
    type: Literal["number", "category", "time"]
    format: str | None       # Format string


class ChartSeriesConfig(TypedDict, total=False):
    """Configuration for a chart data series."""

    key: str                 # Data key
    name: str                # Display name
    color: str | None        # Series color
    type: Literal["line", "bar", "area"] | None


class ChartConfig(TypedDict, total=False):
    """Configuration for chart widgets (line, bar, area)."""

    x_axis: ChartAxisConfig
    y_axis: ChartAxisConfig
    series: list[ChartSeriesConfig]
    stacked: bool
    show_legend: bool
    show_grid: bool


class PieChartConfig(TypedDict, total=False):
    """Configuration for pie/donut chart widgets."""

    value_key: str           # Key for segment value
    label_key: str           # Key for segment label
    colors: list[str] | None # Custom color palette
    show_legend: bool
    show_labels: bool
    inner_radius: int | None # For donut chart (0 = pie)


class TableColumnConfig(TypedDict, total=False):
    """Configuration for a table column."""

    key: str                 # Data key
    header: str              # Column header
    width: int | None        # Column width
    align: Literal["left", "center", "right"]
    format: str | None       # Format string
    sortable: bool


class TableConfig(TypedDict, total=False):
    """Configuration for table widgets."""

    columns: list[TableColumnConfig]
    row_key: str             # Key for unique row identifier
    page_size: int
    show_pagination: bool
    sortable: bool
    filterable: bool


class HeatmapConfig(TypedDict, total=False):
    """Configuration for heatmap widgets."""

    x_key: str               # Key for x-axis categories
    y_key: str               # Key for y-axis categories
    value_key: str           # Key for cell values
    color_scale: list[str]   # Color gradient
    show_values: bool
    format: str | None       # Format for values


class GaugeConfig(TypedDict, total=False):
    """Configuration for gauge widgets."""

    value_key: str           # Key for gauge value
    min: float               # Minimum value
    max: float               # Maximum value
    thresholds: list[dict[str, Any]]  # Color thresholds
    format: str | None       # Format string


# Union of all widget-specific configs
WidgetSpecificConfig = (
    StatCardConfig
    | ChartConfig
    | PieChartConfig
    | TableConfig
    | HeatmapConfig
    | GaugeConfig
)


class WidgetConfig(TypedDict, total=False):
    """Configuration for a dashboard widget."""

    id: str                  # Unique widget identifier
    type: WidgetType         # Widget type
    title: str               # Widget title
    grid: GridPosition       # Grid position and size
    config: dict[str, Any]   # Widget-specific configuration
    data_endpoint: str | None  # Custom data endpoint (if not default)
    refresh_interval: int | None  # Auto-refresh interval in seconds


# =============================================================================
# Dashboard Configuration
# =============================================================================


class DashboardSection(TypedDict):
    """A section in the dashboard containing widgets."""

    id: str                  # Unique section identifier
    title: str               # Section title
    description: str | None  # Optional description
    widgets: list[WidgetConfig]
    collapsed: bool | None   # Whether section is collapsed by default


class DashboardConfig(TypedDict):
    """Full dashboard configuration for a pipeline."""

    pipeline_id: str         # Pipeline identifier
    title: str               # Dashboard title
    description: str | None  # Optional description
    sections: list[DashboardSection]
    default_time_range: str | None  # Default time range (e.g., "7d", "30d")
    refresh_interval: int | None    # Global refresh interval in seconds


# =============================================================================
# Execution Types
# =============================================================================


class ExecutionStatus(TypedDict, total=False):
    """Status of a pipeline execution."""

    id: str                  # Execution ID
    pipeline_id: str         # Pipeline identifier
    job_id: str | None       # Associated job ID
    business_id: str | None  # Business identifier
    status: Literal["pending", "running", "completed", "failed", "cancelled"]
    stages_requested: list[str]
    stages_completed: list[str]
    current_stage: str | None
    progress: float          # 0.0 to 1.0
    input_summary: dict[str, Any] | None
    result_summary: dict[str, Any] | None
    error_message: str | None
    started_at: str | None
    completed_at: str | None
    created_at: str


class ExecutionRequest(TypedDict, total=False):
    """Request to execute a pipeline."""

    job_id: str | None       # Job ID to process
    business_id: str | None  # Business identifier
    input_data: dict[str, Any] | None  # Direct input data
    stages: list[str] | None  # Stages to run (default: all)
    options: dict[str, Any] | None  # Pipeline-specific options


# =============================================================================
# Pipeline Info Types
# =============================================================================


class PipelineInfo(TypedDict):
    """Summary information about a pipeline."""

    id: str                  # Pipeline ID (e.g., "reviewiq")
    name: str                # Display name
    description: str
    version: str
    is_enabled: bool
    stages: list[str]        # Available stages
    input_type: str          # Expected input type


class PipelineDetail(TypedDict):
    """Detailed pipeline information including metadata."""

    id: str
    name: str
    description: str
    version: str
    is_enabled: bool
    stages: list[str]
    input_type: str
    module_path: str
    config: dict[str, Any] | None
    created_at: str
    updated_at: str
