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

from __future__ import annotations

import json
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_get_command_calls_client(monkeypatch, tmp_path: Path) -> None:
    """The box get subcommand should call its API helper and fetch UUTs."""

    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_get(
            self,
            *,
            token: str,
            box_identifier: str,
        ):
            captured["box_get_token"] = token
            captured["box_get_identifier"] = box_identifier
            return {
                "boxIdentifier": "BOX-001",
                "shipped": False,
                "numberOfUnits": 10,
                "startedDateTime": "2026-02-01T00:00:00Z",
                "finishedDateTime": "2026-02-06T23:59:00Z",
            }

        def box_content(
            self,
            *,
            token: str,
            box_identifier: str,
        ):
            captured["box_content_token"] = token
            captured["box_content_identifier"] = box_identifier
            return [
                {
                    "serialNumber": "SN001",
                    "uutTypeName": "Type-A",
                    "identifierTag": "TAG001",
                },
                {
                    "serialNumber": "SN002",
                    "uutTypeName": "Type-B",
                    "identifierTag": "TAG002",
                },
            ]

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

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

    assert result.exit_code == 0
    assert "BOX-001" in result.stdout
    assert "SN001" in result.stdout
    assert "SN002" in result.stdout
    assert "Type-A" in result.stdout
    assert captured["base_url"] == "https://qrm.local/api"
    assert captured["verify_tls"] is True
    assert captured["box_get_token"] == "TOKEN123"
    assert captured["box_get_identifier"] == "BOX-001"
    assert captured["box_content_token"] == "TOKEN123"
    assert captured["box_content_identifier"] == "BOX-001"


def test_box_get_command_supports_json_output(monkeypatch, tmp_path: Path) -> None:
    """Box get should honor --output json and include both box and content."""

    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 FakeClient:
        def __init__(self, *_: str, **__: str) -> None:  # noqa: D401, ANN001, ANN002, ANN003
            pass

        def box_get(self, **__: str):  # noqa: ANN003
            return {"boxIdentifier": "BOX-001", "shipped": False, "numberOfUnits": 10}

        def box_content(self, **__: str):  # noqa: ANN003
            return [{"serialNumber": "SN001", "uutTypeName": "Type-A"}]

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

    result = runner.invoke(
        cli.app,
        [
            "box",
            "get",
            "BOX-001",
            "--config-path",
            str(config_path),
            "--output",
            "json",
        ],
    )

    assert result.exit_code == 0
    output = json.loads(result.stdout)
    assert output["box"]["boxIdentifier"] == "BOX-001"
    assert output["box"]["shipped"] is False
    assert output["content"][0]["serialNumber"] == "SN001"


def test_box_get_command_handles_client_errors(monkeypatch, tmp_path: Path) -> None:
    """Box get 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_get(self, **__):  # noqa: ANN003
            raise cli.QrmClientError("API error")

        def box_content(self, **__):  # noqa: ANN003
            return []

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

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

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