"""Scatter plot figure factory for correlation views."""

from typing import Any

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go


def create_scatter_figure(
    data: list[dict[str, Any]],
    x_column: str,
    y_column: str,
    name_column: str | None = None,
    size_column: str | None = None,
    color_column: str | None = None,
    title: str | None = None,
    x_title: str | None = None,
    y_title: str | None = None,
    trendline: bool = False,
    color_scale: str = "Blues",
) -> go.Figure:
    """Create scatter plot for correlation visualization.

    Args:
        data: List of data records.
        x_column: Column name for x-axis values.
        y_column: Column name for y-axis values.
        name_column: Column name for point labels (hover).
        size_column: Column name for point sizes.
        color_column: Column name for color encoding.
        title: Optional chart title.
        x_title: X-axis title.
        y_title: Y-axis title.
        trendline: Whether to add OLS trendline.
        color_scale: Plotly color scale for continuous colors.

    Returns:
        Plotly Figure object.
    """
    if not data:
        return _create_empty_figure(title or "Scatter Plot")

    df = pd.DataFrame(data)

    # Build hover_data
    hover_data = {}
    if name_column and name_column in df.columns:
        hover_data[name_column] = True

    # Create scatter plot
    fig = px.scatter(
        df,
        x=x_column,
        y=y_column,
        size=size_column if size_column and size_column in df.columns else None,
        color=color_column if color_column and color_column in df.columns else None,
        color_continuous_scale=color_scale,
        hover_name=name_column,
        trendline="ols" if trendline else None,
        opacity=0.7,
    )

    # Style the markers
    fig.update_traces(
        marker={
            "line": {"width": 1, "color": "rgba(255,255,255,0.3)"},
        },
    )

    # Trendline styling
    if trendline:
        fig.update_traces(
            selector={"mode": "lines"},
            line={"color": "#FF9800", "dash": "dash", "width": 2},
        )

    fig.update_layout(
        title=title,
        paper_bgcolor="rgba(0,0,0,0)",
        plot_bgcolor="rgba(0,0,0,0)",
        font_color="#c9c9c9",
        xaxis={
            "gridcolor": "rgba(128,128,128,0.2)",
            "title": x_title or x_column.replace("_", " ").title(),
            "zeroline": False,
        },
        yaxis={
            "gridcolor": "rgba(128,128,128,0.2)",
            "title": y_title or y_column.replace("_", " ").title(),
            "zeroline": False,
        },
        margin={"l": 10, "r": 10, "t": 40, "b": 10},
        showlegend=color_column is not None,
    )

    return fig


def create_bubble_chart(
    data: list[dict[str, Any]],
    x_column: str,
    y_column: str,
    size_column: str,
    name_column: str | None = None,
    color_column: str | None = None,
    title: str | None = None,
    x_title: str | None = None,
    y_title: str | None = None,
    size_max: int = 50,
) -> go.Figure:
    """Create bubble chart with sized markers.

    Args:
        data: List of data records.
        x_column: Column name for x-axis values.
        y_column: Column name for y-axis values.
        size_column: Column name for bubble sizes.
        name_column: Column name for labels.
        color_column: Column name for colors.
        title: Optional chart title.
        x_title: X-axis title.
        y_title: Y-axis title.
        size_max: Maximum marker size in pixels.

    Returns:
        Plotly Figure object.
    """
    if not data:
        return _create_empty_figure(title or "Bubble Chart")

    df = pd.DataFrame(data)

    fig = px.scatter(
        df,
        x=x_column,
        y=y_column,
        size=size_column,
        color=color_column,
        hover_name=name_column,
        size_max=size_max,
        opacity=0.7,
    )

    fig.update_layout(
        title=title,
        paper_bgcolor="rgba(0,0,0,0)",
        plot_bgcolor="rgba(0,0,0,0)",
        font_color="#c9c9c9",
        xaxis={
            "gridcolor": "rgba(128,128,128,0.2)",
            "title": x_title or x_column.replace("_", " ").title(),
        },
        yaxis={
            "gridcolor": "rgba(128,128,128,0.2)",
            "title": y_title or y_column.replace("_", " ").title(),
        },
        margin={"l": 10, "r": 10, "t": 40, "b": 10},
    )

    return fig


def _create_empty_figure(title: str) -> go.Figure:
    """Create an empty figure with a message."""
    fig = go.Figure()
    fig.add_annotation(
        text="No data available",
        xref="paper",
        yref="paper",
        x=0.5,
        y=0.5,
        showarrow=False,
        font={"size": 14, "color": "#888888"},
    )
    fig.update_layout(
        title=title,
        paper_bgcolor="rgba(0,0,0,0)",
        plot_bgcolor="rgba(0,0,0,0)",
        font_color="#c9c9c9",
        xaxis={"visible": False},
        yaxis={"visible": False},
    )
    return fig
