from __future__ import annotations

from typing import Optional

import typer

from aegro.cli._config import get_client, require_farm
from aegro.cli._errors import handle_error
from aegro.cli._output import OutputFormat, format_output
from aegro.validation import validate_key

weather_app = typer.Typer(help="Registros meteorologicos.")


def _require_pair(val: object, val_flag: str, unit: object, unit_flag: str) -> None:
    """Validate that paired value+unit flags are both present or both absent."""
    if (val is not None) != (unit is not None):
        typer.echo(f"{val_flag} e {unit_flag} devem ser usados juntos.", err=True)
        raise typer.Exit(4)


@weather_app.command("get")
def get_weather_log(
    key: str = typer.Argument(help="Chave unica do registro meteorologico."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Retorna os dados de um registro meteorologico pelo seu identificador.

    EXAMPLES:
      aegro weather get abc123
      aegro weather get abc123 --output table
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        result = client.get(f"/pub/v1/weather-logs/{validate_key(key)}", api_key=api_key)
        if result is None:
            typer.echo("Registro meteorologico nao encontrado.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@weather_app.command("create")
def create_weather_log(
    weather_station_key: str = typer.Option(
        ..., "--weather-station-key", help="Chave da estacao meteorologica."
    ),
    date: str = typer.Option(..., "--date", help="Data do registro (YYYY-MM-DD)."),
    precipitation: Optional[float] = typer.Option(
        None, "--precipitation", help="Magnitude da precipitacao."
    ),
    precipitation_unit: Optional[str] = typer.Option(
        None, "--precipitation-unit", help="Unidade da precipitacao (ex: mm)."
    ),
    temperature: Optional[float] = typer.Option(
        None, "--temperature", help="Magnitude da temperatura."
    ),
    temperature_unit: Optional[str] = typer.Option(
        None, "--temperature-unit", help="Unidade da temperatura (ex: CELSIUS)."
    ),
    humidity: Optional[float] = typer.Option(
        None, "--humidity", help="Umidade relativa do ar (%)."
    ),
    pressure: Optional[float] = typer.Option(
        None, "--pressure", help="Pressao atmosferica em hPa."
    ),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria um novo registro meteorologico.

    EXAMPLES:
      aegro weather create --weather-station-key ws1 --date 2025-06-01 --precipitation 12.5 --precipitation-unit mm
      aegro weather create --weather-station-key ws1 --date 2025-06-01 --temperature 28.0 --temperature-unit CELSIUS --humidity 65.0 --pressure 1013.25
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        # Validate paired params
        _require_pair(precipitation, "--precipitation", precipitation_unit, "--precipitation-unit")
        _require_pair(temperature, "--temperature", temperature_unit, "--temperature-unit")

        body: dict = {
            "weatherStationKey": weather_station_key,
            "date": date,
        }
        if precipitation is not None and precipitation_unit is not None:
            body["precipitation"] = {
                "magnitude": precipitation,
                "unit": precipitation_unit,
            }
        if temperature is not None and temperature_unit is not None:
            body["temperature"] = {
                "magnitude": temperature,
                "unit": temperature_unit,
            }
        if humidity is not None:
            body["relativeHumidity"] = humidity
        if pressure is not None:
            body["atmosphericPressureInHpa"] = pressure
        result = client.post("/pub/v1/weather-logs", api_key=api_key, json_body=body)
        if result is None:
            typer.echo(f"Registro meteorologico criado na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
