// UsStateLookup.cs

using System.IO.Compression;

namespace ReverseGeocode;

/// <summary>
/// Provides the US state lookup functionality.
/// </summary>
public static class UsStateLookup
{
	internal class Geometry
	{
		public List<List<double[]>> coordinates { get; set; }
	}
	internal class UsState
	{
		public string name { get; set; }
		public Geometry geometry { get; set; }
	}

	private static readonly Lazy<List<UsState>> LazyData = new(LoadData);

	private static List<UsState> LoadData()
	{
		var assembly = typeof(UsStateLookup).Assembly;
		using var compressedStream = assembly.GetManifestResourceStream("ReverseGeocode.USSTATES.json.gz");
		using var stream = new GZipStream(compressedStream!, CompressionMode.Decompress);

		using (var ms = new MemoryStream())
		{
			stream.CopyTo(ms);
			ms.Seek(0, SeekOrigin.Begin);
			return System.Text.Json.JsonSerializer.Deserialize<List<UsState>>(System.Text.Encoding.UTF8.GetString(ms.ToArray())) ?? new List<UsState>();
		}
	}

	/// <summary>
	/// Determines the US state for given location coordinates.
	/// </summary>
	/// <param name="latitude">The latitude of the location.</param>
	/// <param name="longitude">The longitude of the location.</param>
	/// <returns>A <string?>, which contains the result of the operation or null if not found.</returns>
	public static string? GetUsState(double latitude, double longitude)
	{
		var p = new double[2] { latitude, longitude };
		foreach (var state in LazyData.Value)
		{
			foreach (var list in state.geometry.coordinates)
			{
				if (Common.IsCoordInsideArrayOfCoords(list, p))
					return state.name;
			}
		}
		return null;
	}
}