"""Tests for the 'box update' command."""

from __future__ import annotations

from pathlib import Path

from typer.testing import CliRunner

from qrm import cli
from qrm import box_commands
from qrm.client import LoginState

runner = CliRunner()


def test_box_update_command_calls_client(monkeypatch, tmp_path: Path) -> None:
    """The box update subcommand should call its API helper."""

    state = LoginState(  # type: ignore[call-arg]
        token="TOKEN123",
        username="alice",
        base_url="https://qrm.local/api",
        verify_tls=True,
    )
    config_path = tmp_path / "login.json"
    config_path.write_text(state.model_dump_json())

    captured = {}

    class FakeClient:
        def __init__(self, base_url: str, verify_tls: bool) -> None:  # noqa: D401
            captured["base_url"] = base_url
            captured["verify_tls"] = verify_tls

        def box_add(
            self,
            *,
            token: str,
            box_identifier: str,
            started_datetime: str | None,
            finished_datetime: str | None,
            number_of_units: int | None,
            shipped: bool,
        ):
            captured["token"] = token
            captured["box_identifier"] = box_identifier
            captured["started"] = started_datetime
            captured["finished"] = finished_datetime
            captured["units"] = number_of_units
            captured["shipped"] = shipped
            return True

    monkeypatch.setattr(box_commands, "QrmClient", FakeClient)

    result = runner.invoke(
        cli.app,
        [
            "box",
            "update",
            "BOX-001",
            "--started",
            "2026-02-01 00:00:00",
            "--finished",
            "2026-02-06 23:59:00",
            "--units",
            "10",
            "--shipped",
            "--config-path",
            str(config_path),
        ],
    )

    assert result.exit_code == 0
    assert captured == {
        "base_url": "https://qrm.local/api",
        "verify_tls": True,
        "token": "TOKEN123",
        "box_identifier": "BOX-001",
        "started": "2026-02-01 00:00:00",
        "finished": "2026-02-06 23:59:00",
        "units": 10,
        "shipped": True,
    }


def test_box_update_command_minimal_args(monkeypatch, tmp_path: Path) -> None:
    """Box update should work with just the box identifier."""

    state = LoginState(  # type: ignore[call-arg]
        token="TOKEN123",
        username="alice",
        base_url="https://qrm.local/api",
        verify_tls=True,
    )
    config_path = tmp_path / "login.json"
    config_path.write_text(state.model_dump_json())

    captured = {}

    class FakeClient:
        def __init__(self, base_url: str, verify_tls: bool) -> None:  # noqa: D401
            captured["base_url"] = base_url
            captured["verify_tls"] = verify_tls

        def box_add(self, **kwargs):  # noqa: ANN003
            captured.update(kwargs)
            return {"success": True}

    monkeypatch.setattr(box_commands, "QrmClient", FakeClient)

    result = runner.invoke(
        cli.app,
        [
            "box",
            "update",
            "BOX-MINIMAL",
            "--config-path",
            str(config_path),
        ],
    )

    assert result.exit_code == 0
    assert captured["box_identifier"] == "BOX-MINIMAL"
    assert captured["shipped"] is False
    assert captured["started_datetime"] is None
    assert captured["finished_datetime"] is None
    assert captured["number_of_units"] is None


def test_box_update_command_handles_client_errors(monkeypatch, tmp_path: Path) -> None:
    """Box update errors should surface as helpful messages with exit code 1."""

    state = LoginState(  # type: ignore[call-arg]
        token="TOKEN123",
        username="alice",
        base_url="https://qrm.local/api",
        verify_tls=True,
    )
    config_path = tmp_path / "login.json"
    config_path.write_text(state.model_dump_json())

    class ExplodingClient:
        def __init__(self, *_, **__):  # noqa: D401, ANN002, ANN003
            pass

        def box_add(self, **__):  # noqa: ANN003
            raise cli.QrmClientError("API error")

    monkeypatch.setattr(box_commands, "QrmClient", ExplodingClient)

    result = runner.invoke(
        cli.app,
        [
            "box",
            "update",
            "BOX-ERROR",
            "--config-path",
            str(config_path),
        ],
    )

    assert result.exit_code == 1
    assert "Box update failed" in result.stdout
