"""Test for DNF/scratched logic fix and distance conversion."""


def test_dnf_detection_from_placing():
    """Test that non-numeric placing values are detected as DNF."""
    # Test case 1: DNF placing
    runner_data_dnf = {
        "horseId": 1,
        "horseName": "Test Horse",
        "scratched": False,
        "result": {"placing": "DNF"},
        "driver": {"driverId": 1, "driverName": "Test Driver"},
        "trainer": {"trainerId": 1, "trainerName": "Test Trainer"},
    }

    # We can't actually run upsert without a real database, but we can test the logic
    # by extracting the relevant code
    result = runner_data_dnf.get("result", {})
    placing_str = result.get("placing")

    placing = None
    did_not_finish = False

    if placing_str:
        placing_str = str(placing_str).strip()
        if placing_str.isdigit():
            placing = int(placing_str)
            did_not_finish = False
        elif placing_str:
            placing = None
            did_not_finish = True

    scratched = runner_data_dnf.get("scratched", False)
    if scratched:
        placing = None
        did_not_finish = False

    assert placing is None, "DNF should have NULL placing"
    assert did_not_finish is True, "DNF should have did_not_finish=True"


def test_scratched_not_dnf():
    """Test that scratched horses are NOT marked as DNF."""
    # Test case: scratched horse
    runner_data_scratched = {
        "horseId": 2,
        "horseName": "Scratched Horse",
        "scratched": True,
        "result": {},
    }

    result = runner_data_scratched.get("result", {})
    placing_str = result.get("placing")

    placing = None
    did_not_finish = False

    if placing_str:
        placing_str = str(placing_str).strip()
        if placing_str.isdigit():
            placing = int(placing_str)
            did_not_finish = False
        elif placing_str:
            placing = None
            did_not_finish = True

    scratched = runner_data_scratched.get("scratched", False)
    if scratched:
        placing = None
        did_not_finish = False

    assert placing is None, "Scratched horse should have NULL placing"
    assert (
        did_not_finish is False
    ), "Scratched horse should have did_not_finish=False (never started)"


def test_numeric_placing():
    """Test that numeric placing values are parsed correctly."""
    runner_data_winner = {
        "horseId": 3,
        "horseName": "Winner",
        "scratched": False,
        "result": {"placing": "1"},
    }

    result = runner_data_winner.get("result", {})
    placing_str = result.get("placing")

    placing = None
    did_not_finish = False

    if placing_str:
        placing_str = str(placing_str).strip()
        if placing_str.isdigit():
            placing = int(placing_str)
            did_not_finish = False
        elif placing_str:
            placing = None
            did_not_finish = True

    scratched = runner_data_winner.get("scratched", False)
    if scratched:
        placing = None
        did_not_finish = False

    assert placing == 1, "Winner should have placing=1"
    assert did_not_finish is False, "Finisher should have did_not_finish=False"


def test_distance_yards_conversion():
    """Test that yard distances are converted to metres."""
    # Test case: 1760 yards (1 mile) = 1609 metres
    race_data_yards = {
        "raceNumber": 1,
        "distance": {
            "units": "Yards",
            "distance": 1760,
        },
        "raceGait": "Pace",
        "startType": "Mobile",
    }

    distance_obj = race_data_yards.get("distance", {})
    if isinstance(distance_obj, dict):
        distance_value = distance_obj.get("distance")
        units = distance_obj.get("units", "Metres")

        if distance_value and units == "Yards":
            distance_m = int(distance_value * 0.9144)
        else:
            distance_m = distance_value
    else:
        distance_m = distance_obj

    assert (
        distance_m == 1609
    ), f"1760 yards should convert to 1609 metres, got {distance_m}"


def test_distance_metres_no_conversion():
    """Test that metre distances are not converted."""
    race_data_metres = {
        "raceNumber": 2,
        "distance": {
            "units": "Metres",
            "distance": 2000,
        },
        "raceGait": "Trot",
        "startType": "Stand",
    }

    distance_obj = race_data_metres.get("distance", {})
    if isinstance(distance_obj, dict):
        distance_value = distance_obj.get("distance")
        units = distance_obj.get("units", "Metres")

        if distance_value and units == "Yards":
            distance_m = int(distance_value * 0.9144)
        else:
            distance_m = distance_value
    else:
        distance_m = distance_obj

    assert distance_m == 2000, f"2000 metres should stay 2000 metres, got {distance_m}"


def test_dq_detection():
    """Test that DQ (disqualified) is detected as DNF."""
    runner_data_dq = {
        "horseId": 4,
        "horseName": "Disqualified Horse",
        "scratched": False,
        "result": {"placing": "DQ"},
    }

    result = runner_data_dq.get("result", {})
    placing_str = result.get("placing")

    placing = None
    did_not_finish = False

    if placing_str:
        placing_str = str(placing_str).strip()
        if placing_str.isdigit():
            placing = int(placing_str)
            did_not_finish = False
        elif placing_str:
            placing = None
            did_not_finish = True

    assert placing is None, "DQ should have NULL placing"
    assert did_not_finish is True, "DQ should have did_not_finish=True"


if __name__ == "__main__":
    # Run tests manually
    print("Testing DNF detection...")
    test_dnf_detection_from_placing()
    print("✓ DNF detection works")

    print("Testing scratched logic...")
    test_scratched_not_dnf()
    print("✓ Scratched logic works")

    print("Testing numeric placing...")
    test_numeric_placing()
    print("✓ Numeric placing works")

    print("Testing yards conversion...")
    test_distance_yards_conversion()
    print("✓ Yards to metres conversion works")

    print("Testing metres (no conversion)...")
    test_distance_metres_no_conversion()
    print("✓ Metres stay unchanged")

    print("Testing DQ detection...")
    test_dq_detection()
    print("✓ DQ detection works")

    print("\nAll tests passed! ✓")
