"""CLI commands for native Google Sheets charts."""

from __future__ import annotations

import json
import sys
from typing import List, Optional

import click

from g_gremlin import charts as charts_mod
from g_gremlin.contracts import ChartResult

EXIT_REMOTE_ERROR = 1


@click.group("chart")
def chart() -> None:
    """
    Google Sheets chart helpers (native charts).
    """


@chart.command("add")
@click.argument("spreadsheet_id")
@click.argument("sheet_name")
@click.option(
    "--type",
    "chart_type",
    required=True,
    type=click.Choice(["column", "line", "pie", "scatter", "area", "bar"], case_sensitive=False),
    help="Chart type.",
)
@click.option(
    "--range",
    "data_range",
    help="Data range in A1 notation (e.g., 'A1:C100').",
)
@click.option("--x-col", help="Column header for X axis.")
@click.option("--y-col", help="Column header for Y axis.")
@click.option(
    "--series-cols",
    multiple=True,
    help="Additional series columns (repeatable or comma-separated).",
)
@click.option("--title", help="Chart title.")
@click.option("--x-axis-title", help="X axis title.")
@click.option("--y-axis-title", help="Y axis title.")
@click.option(
    "--anchor",
    "anchor_cell",
    default="E1",
    show_default=True,
    help="Top-left anchor cell for chart placement.",
)
@click.option(
    "--replace",
    is_flag=True,
    help="Replace existing chart with same title (requires --title).",
)
@click.option("--json", "json_output", is_flag=True, help="Emit JSON output.")
def chart_add(
    spreadsheet_id: str,
    sheet_name: str,
    chart_type: str,
    data_range: Optional[str],
    x_col: Optional[str],
    y_col: Optional[str],
    series_cols: tuple[str, ...],
    title: Optional[str],
    x_axis_title: Optional[str],
    y_axis_title: Optional[str],
    anchor_cell: str,
    replace: bool,
    json_output: bool,
) -> None:
    """
    Add a native Google Sheets chart.

    Note: series columns should be numeric; text series may render empty. Use
    "g-gremlin write --user-entered" to coerce numeric strings before charting.
    """
    series_list = _parse_series_cols(series_cols)

    try:
        result = charts_mod.add_chart(
            spreadsheet_id,
            sheet_name,
            chart_type,
            data_range=data_range,
            x_col=x_col,
            y_col=y_col,
            series_cols=series_list or None,
            title=title,
            x_axis_title=x_axis_title,
            y_axis_title=y_axis_title,
            anchor_cell=anchor_cell,
            replace=replace,
        )
    except Exception as exc:
        if json_output:
            payload = {
                "status": "error",
                "error": str(exc),
            }
            click.echo(json.dumps(payload, indent=2))
        else:
            click.echo(f"Error: {exc}", err=True)
        sys.exit(EXIT_REMOTE_ERROR)

    if json_output:
        payload = _chart_result_payload(result)
        payload["status"] = "success"
        click.echo(json.dumps(payload, indent=2))
        return

    message = f"Chart created (id {result.chart_id}) at {result.anchor}."
    if result.title:
        message = f"Chart '{result.title}' created (id {result.chart_id}) at {result.anchor}."
    if result.replaced:
        message = "Replaced existing chart(s). " + message
    click.echo(message)


@chart.command("list")
@click.argument("spreadsheet_id")
@click.argument("sheet_name")
@click.option("--json", "json_output", is_flag=True, help="Emit JSON output.")
def chart_list(spreadsheet_id: str, sheet_name: str, json_output: bool) -> None:
    """
    List charts in a sheet tab.
    """
    try:
        charts = charts_mod.list_charts(spreadsheet_id, sheet_name)
    except Exception as exc:
        if json_output:
            click.echo(json.dumps({"status": "error", "error": str(exc)}, indent=2))
        else:
            click.echo(f"Error: {exc}", err=True)
        sys.exit(EXIT_REMOTE_ERROR)

    if json_output:
        payload = {
            "status": "success",
            "charts": [chart.to_dict() for chart in charts],
        }
        click.echo(json.dumps(payload, indent=2))
        return

    if not charts:
        click.echo("No charts found.")
        return

    for chart in charts:
        anchor = chart.anchor or "-"
        title = chart.title or "(untitled)"
        click.echo(
            f"ID {chart.chart_id} | {chart.chart_type} | {title} | anchor {anchor}"
        )


def _parse_series_cols(values: tuple[str, ...]) -> List[str]:
    series: List[str] = []
    for raw in values:
        if not raw:
            continue
        parts = [p.strip() for p in raw.split(",") if p.strip()]
        for part in parts:
            if part not in series:
                series.append(part)
    return series


def _chart_result_payload(result: ChartResult) -> dict:
    payload = result.to_dict()
    return payload


__all__ = ["chart"]
