"""test utility functions."""

import platform

import geopandas
import pytest
from libpysal.examples import load_example
from numpy.testing import assert_almost_equal
from packaging.version import Version

from tobler.util import h3fy

PY312 = platform.python_version_tuple()[:2] == ("3", "12")
GPD11 = Version(geopandas.__version__) >= Version("1.1")


@pytest.fixture
def sac1():
    s1, s2 = "Sacramento1", "sacramentot2.shp"
    return geopandas.read_file(load_example(s1).get_path(s2))


def test_h3fy(sac1):
    sac_hex = h3fy(sac1, return_geoms=True)
    assert sac_hex.shape == (364, 1)


def test_h3fy_nogeoms(sac1):
    sac_hex = h3fy(sac1, return_geoms=False)
    assert len(sac_hex) == 364


def test_h3fy_nocrs(sac1):
    with pytest.raises(ValueError, match="source geodataframe must have a valid CRS"):
        h3fy(sac1.set_crs(None, allow_override=True), return_geoms=True)


def test_h3fy_diff_crs(sac1):
    sac_hex = h3fy(sac1.to_crs(32710))
    assert sac_hex.shape == (364, 1)
    assert sac_hex.crs.to_string() == "EPSG:32710"


def test_h3fy_projected_us_feet_buffer(sac1):

    # seems to be a floating point difference only affecting Python 3.12?
    records = 393 if PY312 and GPD11 else 396

    sac_hex = h3fy(sac1.to_crs(2871), buffer=True)
    assert sac_hex.shape == (records, 1)
    assert sac_hex.crs.to_string() == "EPSG:2871"


def test_h3fy_projected_international_feet_buffer(sac1):
    with pytest.raises(
        ValueError,
        match="The CRS of source geodataframe uses an unknown measurement unit: `ft`",
    ):
        h3fy(sac1.to_crs(2994), buffer=True)


def test_h3fy_clip(sac1):
    sac_hex = h3fy(sac1, clip=True)
    sac_hex = sac_hex.to_crs(sac_hex.estimate_utm_crs())
    assert_almost_equal(sac_hex.area.sum(), 13131736346.537422, decimal=0)


def test_h3fy_clip_buffer(sac1):
    sac1 = sac1.to_crs(4326)
    with pytest.warns(
        UserWarning,
        match="The source geodataframe is stored in a geographic CRS",
    ):
        sac_hex = h3fy(sac1, clip=True, buffer=True)
    sac_hex = sac_hex.to_crs(sac_hex.estimate_utm_crs())
    sac1 = sac1.to_crs(sac_hex.estimate_utm_crs())
    assert_almost_equal(sac_hex.area.sum(), sac1.area.sum(), decimal=-8)


@pytest.mark.skipif(
    platform.system() == "Windows",
    reason="Unknown precision error on Windows. See #174 for details",
)
def test_h3_multipoly():
    va = geopandas.read_file(load_example("virginia").get_path("virginia.shp"))
    va = va.to_crs(va.estimate_utm_crs())

    va = h3fy(va)
    assert_almost_equal(va.area.sum(), 102888497504.47836, decimal=0)
