"""K-line (candlestick) plotting using matplotlib."""

from __future__ import annotations

from typing import Any, List, Optional

from sd_api.exceptions import PlotError
from sd_api.logging import get_logger
from sd_api.models.kline import KlineBar

logger = get_logger("plot.kline")

try:
    import matplotlib
    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    _HAS_MATPLOTLIB = True
except ImportError:
    _HAS_MATPLOTLIB = False

try:
    import pandas as pd
    _HAS_PANDAS = True
except ImportError:
    _HAS_PANDAS = False


def _check_deps() -> None:
    if not _HAS_MATPLOTLIB:
        raise PlotError("matplotlib is required. Install with: pip install sd-api[plot]")
    if not _HAS_PANDAS:
        raise PlotError("pandas is required. Install with: pip install sd-api[plot]")


def plot_kline(
    bars: List[KlineBar],
    *,
    ax: Optional[Any] = None,
    title: Optional[str] = None,
    figsize: tuple[float, float] = (14, 6),
    color_up: str = "#0ecb81",
    color_down: str = "#f6465d",
) -> Any:
    """Plot a candlestick chart from a list of KlineBars.

    Parameters
    ----------
    bars : List[KlineBar]
        Chronologically ordered K-line bars.
    ax : matplotlib Axes, optional
        Existing Axes to draw on.
    title : str, optional
        Plot title.
    figsize : tuple
        Figure size in inches.
    color_up : str
        Color for bullish (close >= open) candles.
    color_down : str
        Color for bearish candles.

    Returns
    -------
    matplotlib Figure
    """
    _check_deps()
    if not bars:
        raise PlotError("No bars provided")

    df = pd.DataFrame([{
        "ts": b.ts,
        "open": b.open,
        "high": b.high,
        "low": b.low,
        "close": b.close,
    } for b in bars])
    df["ts"] = pd.to_datetime(df["ts"], unit="ms")
    df.set_index("ts", inplace=True)

    fig = None
    if ax is None:
        fig, ax = plt.subplots(figsize=figsize)

    # Candlestick bodies
    up = df[df["close"] >= df["open"]]
    down = df[df["close"] < df["open"]]

    # Draw wicks
    ax.plot(df.index, df["high"], color="#888", linewidth=0.5)
    ax.plot(df.index, df["low"], color="#888", linewidth=0.5)

    # Draw bodies
    w = pd.Timedelta(minutes=4)  # bar width
    if len(up):
        ax.bar(up.index, up["close"] - up["open"],
               bottom=up["open"], width=w, color=color_up, edgecolor=color_up)
    if len(down):
        ax.bar(down.index, down["close"] - down["open"],
               bottom=down["open"], width=w, color=color_down, edgecolor=color_down)

    ax.set_ylabel("Price")
    ax.set_xlabel("Time")
    ax.grid(alpha=0.2)
    if title:
        ax.set_title(title)
    if fig:
        fig.autofmt_xdate()
    return fig if fig else ax.get_figure()
