from __future__ import annotations

import base64

import wzrd.client as client_module
from wzrd.client import WZRDClient


def _client_with_payload(payload):
    client = WZRDClient()
    client._fetch_payload = lambda: payload  # type: ignore[method-assign]
    return client


def _make_quote_account(feed_hash_hex: str, value: int, *, slot: int = 123_456, version: int = 0) -> bytes:
    message = bytes(32) + bytes.fromhex(feed_hash_hex) + value.to_bytes(16, "little", signed=True) + bytes([1])
    count = 1
    offsets_start = 2
    offsets_size = 14
    signature_offset = offsets_start + offsets_size
    public_key_offset = signature_offset + 64
    message_offset = public_key_offset + 32

    offsets = bytearray(offsets_size)
    offsets[0:2] = signature_offset.to_bytes(2, "little")
    offsets[2:4] = (0).to_bytes(2, "little")
    offsets[4:6] = public_key_offset.to_bytes(2, "little")
    offsets[6:8] = (0).to_bytes(2, "little")
    offsets[8:10] = message_offset.to_bytes(2, "little")
    offsets[10:12] = len(message).to_bytes(2, "little")
    offsets[12:14] = (0).to_bytes(2, "little")

    payload = bytearray()
    payload.append(count)
    payload.append(0)
    payload.extend(offsets)
    payload.extend(bytes(64))
    payload.extend(bytes(32))
    payload.extend(message)
    payload.extend(bytes([0]))
    payload.extend(slot.to_bytes(8, "little"))
    payload.append(version)
    payload.extend(b"SBOD")

    account = bytearray()
    account.extend(b"SBOracle")
    account.extend(bytes(32))
    account.extend(len(payload).to_bytes(2, "little"))
    account.extend(payload)
    return bytes(account)


def test_pick_prefers_strict_signal_over_observe():
    client = _client_with_payload(
        {
            "count": 2,
            "models": [
                {
                    "model": "moonshotai/Kimi-K2.5",
                    "trend": "surging",
                    "score": 1.0,
                    "action": "observe",
                    "confidence": "low",
                    "platform": "huggingface",
                },
                {
                    "model": "Qwen/Qwen3.5-35B-A3B",
                    "trend": "accelerating",
                    "score": 0.7,
                    "action": "candidate",
                    "confidence": "normal",
                    "platform": "github",
                },
            ],
        }
    )

    choice = client.pick_details("code")

    assert choice.model == "Qwen/Qwen3.5-35B-A3B"
    assert choice.policy == "strict"
    assert choice.signal_model == "Qwen/Qwen3.5-35B-A3B"


def test_pick_uses_task_platform_bias():
    payload = {
        "count": 2,
        "models": [
            {
                "model": "github/model-a",
                "trend": "stable",
                "score": 0.5,
                "action": "candidate",
                "confidence": "normal",
                "platform": "github",
            },
            {
                "model": "openrouter/model-b",
                "trend": "stable",
                "score": 0.5,
                "action": "candidate",
                "confidence": "normal",
                "platform": "openrouter",
            },
        ],
    }

    client = _client_with_payload(payload)

    assert client.pick("code") == "github/model-a"
    assert client.pick("chat") == "openrouter/model-b"


def test_pick_with_candidates_matches_aliases():
    client = _client_with_payload(
        {
            "count": 2,
            "models": [
                {
                    "model": "Qwen/Qwen3.5-9B",
                    "trend": "accelerating",
                    "score": 0.8,
                    "action": "candidate",
                    "confidence": "normal",
                    "platform": "openrouter",
                },
                {
                    "model": "anthropic/claude-sonnet-4.6",
                    "trend": "stable",
                    "score": 0.4,
                    "action": "candidate",
                    "confidence": "normal",
                    "platform": "openrouter",
                },
            ],
        }
    )

    choice = client.pick(
        "code",
        candidates=[
            "openrouter/qwen/qwen3.5-9b",
            "anthropic/claude-sonnet-4.6",
        ],
    )

    assert choice == "openrouter/qwen/qwen3.5-9b"


def test_compare_returns_verdict():
    client = _client_with_payload(
        {
            "count": 2,
            "models": [
                {
                    "model": "Qwen/Qwen3.5-35B-A3B",
                    "trend": "surging",
                    "score": 0.7,
                    "action": "candidate",
                    "confidence": "normal",
                    "platform": "github",
                },
                {
                    "model": "anthropic/claude-sonnet-4.6",
                    "trend": "stable",
                    "score": 0.2,
                    "action": "candidate",
                    "confidence": "normal",
                    "platform": "openrouter",
                },
            ],
        }
    )

    verdict = client.compare("Qwen/Qwen3.5-35B-A3B", "anthropic/claude-sonnet-4.6")

    assert verdict["winner"] == "Qwen/Qwen3.5-35B-A3B"
    assert "stronger momentum" in verdict["verdict"]


def test_compare_unmatched_returns_not_tracked():
    client = _client_with_payload({"count": 0, "models": []})

    verdict = client.compare("not-tracked-a", "not-tracked-b")

    assert verdict["winner"] is None
    assert "tracked" in verdict["verdict"]
    assert verdict["a"]["status"] == "not_tracked"
    assert verdict["b"]["status"] == "not_tracked"


def test_feed_meta_parses_envelope():
    client = _client_with_payload(
        {
            "contract_version": "wzrd.momentum.v1",
            "generated_at": "2026-03-18T23:31:00Z",
            "provenance": {"source": "momentum_aggregator", "root_seq": 1842},
            "count": 0,
            "models": [],
        }
    )

    meta = client.feed_meta()

    assert meta is not None
    assert meta.contract_version == "wzrd.momentum.v1"
    assert meta.generated_at == "2026-03-18T23:31:00Z"
    assert meta.source == "momentum_aggregator"
    assert meta.root_seq == 1842


def test_feed_meta_returns_none_without_envelope():
    client = _client_with_payload({"count": 0, "models": []})

    meta = client.feed_meta()

    assert meta is None


def test_pick_uses_env_api_url_when_not_explicit(monkeypatch):
    captured: dict[str, object] = {}

    class FakePicker:
        def pick(self, **kwargs):
            return "ok"

    def fake_get_client(**kwargs):
        captured.update(kwargs)
        return FakePicker()

    monkeypatch.setenv("WZRD_API_URL", "https://example.test/public")
    monkeypatch.setattr(client_module, "get_client", fake_get_client)

    result = client_module.pick("code")

    assert result == "ok"
    assert captured["api_url"] == "https://example.test/public"


def test_pick_explicit_api_url_overrides_env(monkeypatch):
    captured: dict[str, object] = {}

    class FakePicker:
        def pick(self, **kwargs):
            return "ok"

    def fake_get_client(**kwargs):
        captured.update(kwargs)
        return FakePicker()

    monkeypatch.setenv("WZRD_API_URL", "https://example.test/public")
    monkeypatch.setattr(client_module, "get_client", fake_get_client)

    result = client_module.pick("code", api_url="https://example.test/premium")

    assert result == "ok"
    assert captured["api_url"] == "https://example.test/premium"


def test_switchboard_feed_source_decodes_quote_accounts():
    qwen_feed = next(entry for entry in client_module._SWITCHBOARD_FEEDS if entry["model"] == "Qwen/Qwen3.5-27B")
    llama_feed = next(entry for entry in client_module._SWITCHBOARD_FEEDS if entry["model"] == "meta-llama/Llama-3.3-70B-Instruct")

    result = {
        "context": {"slot": 200_000},
        "value": [
            None if entry["model"] not in {qwen_feed["model"], llama_feed["model"]} else {
                "data": [
                    base64.b64encode(
                        _make_quote_account(
                            entry["feed_hash"],
                            2_000_000_000_000_000_000 if entry["model"] == qwen_feed["model"] else 1_000_000_000_000_000_000,
                            slot=199_500,
                        )
                    ).decode("ascii"),
                    "base64",
                ]
            }
            for entry in client_module._SWITCHBOARD_FEEDS
        ],
    }

    payload = client_module._switchboard_payload_from_rpc_result(result, limit=10)
    client = WZRDClient(feed_source="switchboard")
    client._fetch_switchboard_payload = lambda: payload  # type: ignore[method-assign]

    choice = client.pick_details("code")
    meta = client.feed_meta()

    assert choice.model == "Qwen/Qwen3.5-27B"
    assert choice.trend == "onchain"
    assert choice.confidence == "high"
    assert "switchboard_on_demand" in choice.reason
    assert meta is not None
    assert meta.source == "switchboard_on_demand"


def test_auto_feed_source_falls_back_to_switchboard_when_api_empty():
    client = WZRDClient(feed_source="auto")
    client._fetch_api_payload = lambda: {"count": 0, "models": []}  # type: ignore[method-assign]
    client._fetch_switchboard_payload = lambda: {  # type: ignore[method-assign]
        "contract_version": "wzrd.switchboard.v1",
        "generated_at": "2026-03-23T00:00:00Z",
        "provenance": {"source": "switchboard_on_demand", "root_seq": None},
        "count": 1,
        "models": [
            {
                "model": "Qwen/Qwen3.5-27B",
                "score": 2.0,
                "trend": "onchain",
                "action": "onchain",
                "confidence": "high",
                "platform": "huggingface",
                "capabilities": ["code", "chat", "reasoning", "vision", "text"],
                "source": "switchboard_on_demand",
            }
        ],
    }

    assert client.pick("code") == "Qwen/Qwen3.5-27B"
