// CaProvinceLookup.cs

using System.IO.Compression;

namespace ReverseGeocode;

/// <summary>
/// Provides the Canadian province lookup functionality.
/// </summary>
public static class CaProvinceLookup
{
	internal class Geometry
	{
		public List<List<double[]>> coordinates { get; set; }
	}
	internal class CaProvince
	{
        public string name_en { get; set; }
        public string prov_type { get; set; }
        public Geometry geometry { get; set; }
	}

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

	private static List<CaProvince> LoadData()
	{
		var assembly = typeof(CaProvinceLookup).Assembly;
		using var compressedStream = assembly.GetManifestResourceStream("ReverseGeocode.CAPROVINCES.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<CaProvince>>(System.Text.Encoding.UTF8.GetString(ms.ToArray())) ?? new List<CaProvince>();
		}
	}

	/// <summary>
	/// Determines the Canadian province/territory 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? GetCaProvince(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_en;
			}
		}
		return null;
	}
}