from __future__ import annotations

import json
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

activities_app = typer.Typer(help="Atividades agricolas e planejamento.")


@activities_app.command("get")
def get_activity(
    key: str = typer.Argument(help="Chave unica da atividade."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Retorna os dados de uma atividade pelo seu identificador.

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


@activities_app.command("list")
def list_activities(
    crop_key: Optional[str] = typer.Option(None, "--crop-key", help="Chave da safra para filtrar."),
    status: Optional[list[str]] = typer.Option(
        None, "--status", help="Status da atividade (repetivel)."
    ),
    type: Optional[list[str]] = typer.Option(None, "--type", help="Tipo da atividade (repetivel)."),
    page: int = typer.Option(1, "--page", help="Numero da pagina."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Lista atividades da fazenda ativa com filtros opcionais.

    EXAMPLES:
      aegro activities list
      aegro activities list --crop-key abc123
      aegro activities list --status PLANNED --type SOWING --page 2
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "requiredPageNumber": page,
            "maximumItemsPerPageCount": 50,
        }
        if crop_key is not None:
            body["cropKeys"] = [crop_key]
        if status:
            body["statuses"] = status
        if type:
            body["types"] = type
        result = client.post("/pub/v1/activities/filter", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Nenhuma atividade encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@activities_app.command("plan")
def get_activity_plan(
    key: str = typer.Argument(help="Chave unica da atividade."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Retorna o plano de uma atividade pelo identificador da atividade.

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


@activities_app.command("realizations")
def list_realizations(
    activity_key: Optional[str] = typer.Option(None, "--activity-key", help="Chave da atividade."),
    crop_key: Optional[str] = typer.Option(None, "--crop-key", help="Chave da safra."),
    start_date: Optional[str] = typer.Option(
        None, "--start-date", help="Data inicial (YYYY-MM-DD)."
    ),
    end_date: Optional[str] = typer.Option(None, "--end-date", help="Data final (YYYY-MM-DD)."),
    page: int = typer.Option(1, "--page", help="Numero da pagina."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Lista realizacoes de atividades com filtros opcionais.

    EXAMPLES:
      aegro activities realizations --activity-key abc123
      aegro activities realizations --crop-key c1 --start-date 2025-01-01
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "requiredPageNumber": page,
            "maximumItemsPerPageCount": 50,
        }
        if activity_key is not None:
            body["activityKeys"] = [activity_key]
        if crop_key is not None:
            body["cropKeys"] = [crop_key]
        if start_date is not None:
            body["startDate"] = start_date
        if end_date is not None:
            body["endDate"] = end_date
        result = client.post(
            "/pub/v1/activities/realizations/filter",
            api_key=api_key,
            json_body=body,
        )
        if result is None:
            typer.echo("Nenhuma realizacao encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


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

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


@activities_app.command("get-realization")
def get_realization(
    key: str = typer.Argument(help="Chave unica da realizacao."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Retorna os dados de uma realizacao de atividade pelo seu identificador.

    EXAMPLES:
      aegro activities get-realization real-1
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        result = client.get(
            f"/pub/v1/activities/realizations/{validate_key(key)}",
            api_key=api_key,
        )
        if result is None:
            typer.echo("Realizacao nao encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@activities_app.command("create-plan")
def create_plan(
    crop_key: str = typer.Option(..., "--crop-key", help="Chave da safra."),
    type: str = typer.Option(
        ...,
        "--type",
        help="Tipo: SOWING|APPLICATION|FERTILIZATION|HARVEST|SEED_TREATMENT|PEST_SCOUTING|TILLAGE|OTHER.",
    ),
    start_date: str = typer.Option(..., "--start-date", help="Data de inicio (YYYY-MM-DD)."),
    activity_key: Optional[str] = typer.Option(
        None, "--activity-key", help="Chave da atividade (opcional)."
    ),
    crop_glebe_key: Optional[list[str]] = typer.Option(
        None,
        "--crop-glebe-key",
        help="Chave de talhao de safra (repetivel).",
    ),
    end_date: Optional[str] = typer.Option(None, "--end-date", help="Data final (YYYY-MM-DD)."),
    observations: Optional[str] = typer.Option(None, "--observations", help="Observacoes."),
    inputs: Optional[str] = typer.Option(None, "--inputs", help="Insumos como string JSON."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria um novo plano de atividade.

    EXAMPLES:
      aegro activities create-plan --crop-key c1 --type SOWING --start-date 2025-06-01
      aegro activities create-plan --crop-key c1 --type APPLICATION --start-date 2025-06-01 --end-date 2025-06-15 --observations "Aplicacao de defensivo"
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "cropKey": crop_key,
            "type": type,
            "startDate": start_date,
        }
        if activity_key is not None:
            body["activityKey"] = activity_key
        if crop_glebe_key:
            body["cropGlebeKeys"] = crop_glebe_key
        if end_date is not None:
            body["endDate"] = end_date
        if observations is not None:
            body["observations"] = observations
        if inputs is not None:
            try:
                body["inputs"] = json.loads(inputs)
            except json.JSONDecodeError as exc:
                typer.echo(f"--inputs contem JSON invalido: {exc}", err=True)
                raise typer.Exit(4)
        result = client.post("/pub/v1/activities/plan", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Falha ao criar plano de atividade.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
