"""SP40: tests for `cyclone validate-837 <file>` CLI."""
from __future__ import annotations

import json
from pathlib import Path

import httpx
import pytest
from click.testing import CliRunner

from cyclone import edifabric
from cyclone.cli import validate_837_cmd


_TEST_KEY = "test-edifabric-key-0123456789abcdef"


def _make_client(handler):
    transport = httpx.MockTransport(handler)
    return httpx.Client(transport=transport, timeout=10.0)


def _install(handler):
    edifabric.set_transport_factory(lambda: _make_client(handler))


@pytest.fixture(autouse=True)
def _reset_transport():
    yield
    edifabric._reset_transport_factory()


# --- happy path -------------------------------------------------------


def test_validate_837_success_prints_status_and_exits_zero(tmp_path):
    """A clean file with Status='success' from Edifabric exits 0 and
    prints the OperationResult summary."""
    fixture = Path("/home/tyler/dev/cyclone/backend/tests/fixtures/co_medicaid_837p.txt")
    sample = tmp_path / "ok.x12"
    sample.write_text(fixture.read_text())

    def handler(request: httpx.Request) -> httpx.Response:
        if request.url.path.endswith("/read"):
            return httpx.Response(200, json=[{
                "SegmentDelimiter": "~",
                "DataElementDelimiter": "*",
                "ISA": {"InterchangeControlNumber_13": "000000001"},
                "Groups": [],
                "IEATrailers": [],
            }])
        if request.url.path.endswith("/validate"):
            return httpx.Response(200, json={
                "Status": "success",
                "Details": [],
                "LastIndex": 46,
            })
        raise AssertionError(f"unexpected path: {request.url.path}")

    _install(handler)
    runner = CliRunner()
    result = runner.invoke(validate_837_cmd, [str(sample), "--api-key", _TEST_KEY])
    assert result.exit_code == 0, result.output
    assert "Status: success" in result.output
    assert "Details: 0 item(s)" in result.output


def test_validate_837_error_status_exits_two_and_prints_details(tmp_path):
    """Status='error' from Edifabric exits 2 and prints the offending
    segment + message for each Details item."""
    sample = tmp_path / "bad.x12"
    sample.write_text("ISA*bad~")

    def handler(request: httpx.Request) -> httpx.Response:
        if request.url.path.endswith("/read"):
            return httpx.Response(200, json=[{
                "SegmentDelimiter": "~",
                "DataElementDelimiter": "*",
                "ISA": {"InterchangeControlNumber_13": "000000001"},
                "Groups": [],
                "IEATrailers": [],
            }])
        if request.url.path.endswith("/validate"):
            return httpx.Response(200, json={
                "Status": "error",
                "Details": [
                    {"SegmentId": "PER", "Message": "PER-04 is required", "Status": "error"},
                    {"SegmentId": "SBR", "Message": "SBR-09 is required", "Status": "error"},
                ],
                "LastIndex": 5,
            })
        raise AssertionError(f"unexpected path: {request.url.path}")

    _install(handler)
    runner = CliRunner()
    result = runner.invoke(validate_837_cmd, [str(sample), "--api-key", _TEST_KEY])
    assert result.exit_code == 2, result.output
    assert "Status: error" in result.output
    assert "PER: PER-04 is required" in result.output
    assert "SBR: SBR-09 is required" in result.output


def test_validate_837_missing_api_key_exits_one(tmp_path, monkeypatch):
    """With no API key anywhere (env var unset, keychain empty), the
    CLI exits 1 and surfaces a clear 'API key not configured' error."""
    monkeypatch.delenv("CYCLONE_EDIFABRIC_API_KEY", raising=False)
    sample = tmp_path / "any.x12"
    sample.write_text("ISA*...~")

    def handler(request: httpx.Request) -> httpx.Response:
        raise AssertionError("transport should not be called when key is missing")

    _install(handler)
    runner = CliRunner()
    result = runner.invoke(validate_837_cmd, [str(sample)])
    assert result.exit_code == 1, result.output
    assert "API key not configured" in result.output


def test_validate_837_file_not_found_exits_two():
    """Click's path validation rejects a missing file before the
    command body runs (exits 2 via Click's UsageError)."""
    runner = CliRunner()
    result = runner.invoke(validate_837_cmd, ["/nonexistent/path.x12", "--api-key", _TEST_KEY])
    assert result.exit_code == 2, result.output