"""Tests for the parser modules."""

from __future__ import annotations

import pytest

from aiosolax.parsers import get_parser
from aiosolax.parsers.x1_hybrid_gen4 import X1HybridGen4Parser


def test_parser_registry():
    """Test that the parser registry contains the X1-Hybrid Gen4."""
    parser = get_parser(15)
    assert parser is not None
    assert isinstance(parser, X1HybridGen4Parser)


def test_parser_registry_unknown_type():
    """Test that unknown types return None."""
    assert get_parser(999) is None


def test_x1_hybrid_gen4_scaling(x1_hybrid_gen4_fixture):
    """Test scaling, signing, and 32-bit combine for X1-Hybrid Gen4."""
    parser = X1HybridGen4Parser()
    data = parser.parse(x1_hybrid_gen4_fixture["Data"])

    # /10 scaling
    assert data.grid_voltage == pytest.approx(241.4)
    assert data.pv1_voltage == pytest.approx(321.5)
    assert data.pv2_voltage == pytest.approx(187.0)
    assert data.pv1_current == pytest.approx(8.9)
    assert data.pv2_current == pytest.approx(4.2)
    assert data.today_pv_energy == pytest.approx(4.5)

    # /100 scaling
    assert data.grid_frequency == pytest.approx(49.93)
    assert data.battery_voltage == pytest.approx(235.10)

    # Signed values (two's complement)
    # grid_current: 32 → 3.2 (positive, signed)
    assert data.grid_current == pytest.approx(3.2)
    # battery_current: 65471 → (65471 - 65536) = -65 → -0.65
    assert data.battery_current == pytest.approx(-0.65)
    # battery_power: -350 → Python already treats as negative int,
    # but raw 16-bit would be 65186 → 65186-65536 = -350
    # The fixture has -350 which in JSON is already negative
    # In real dongle data this would be unsigned 65186
    # grid_power_io: -120 (signed, importing from grid)

    # No scaling (unsigned)
    assert data.grid_power == 780
    assert data.pv1_power == 2861
    assert data.pv2_power == 786
    assert data.battery_soc == 45
    assert data.inverter_temperature == 34

    # 32-bit combine: data[11] + data[12] * 65536
    # total_pv_energy: 1523 + 2 * 65536 = 132595, /10 = 13259.5
    assert data.total_pv_energy == pytest.approx(13259.5)

    # total_feed_in_energy: 15234 + 0 * 65536 = 15234, /100 = 152.34
    assert data.total_feed_in_energy == pytest.approx(152.34)

    # total_consumption: 87650 + 1 * 65536 = 153186, /100 = 1531.86
    assert data.total_consumption == pytest.approx(1531.86)


def test_x1_hybrid_gen4_all_fields_present(x1_hybrid_gen4_fixture):
    """Test that all 21 InverterData fields are populated."""
    parser = X1HybridGen4Parser()
    data = parser.parse(x1_hybrid_gen4_fixture["Data"])

    from dataclasses import fields as dc_fields
    from aiosolax.models import InverterData

    for f in dc_fields(InverterData):
        value = getattr(data, f.name)
        assert value is not None, f"Field {f.name} is None"


def test_parser_properties():
    """Test parser metadata properties."""
    parser = X1HybridGen4Parser()
    assert parser.inverter_type == 15
    assert parser.model_name == "X1-Hybrid Gen4"
    assert len(parser.registers) == 21
