using AprsSharp.Parsers.Aprs;
using GeoCoordinatePortable;
using log4net;
using NmeaParser.Messages;
using skyscraper5.Aprs.AprsSharp;
using skyscraper5.Skyscraper.Plugins;
using skyscraper8.Skyscraper.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper5.Aprs
{
	internal class LX9SESMessageReceiver : IAprsMessageReciever
	{
		private readonly LX9SESStorage _storage;
		public DateTime? currentTime;
		private static PluginLogger logger = PluginLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

		public LX9SESMessageReceiver(LX9SESStorage storage)
		{
			this._storage = storage;
		}

		public void OnAprsPosition(string packetSender, GeoCoordinate positionCoordinates, string? piComment)
		{
			if (!currentTime.HasValue)
				return;

			if (positionCoordinates.Longitude == 0.0 || positionCoordinates.Latitude == 0.0)
				return;

			if (_storage.AprsPosition(currentTime.Value, packetSender, positionCoordinates, piComment))
			{
				logger.Log(PluginLogLevel.Info,String.Format("[{3}] {0} is at {1}, {2}", packetSender, positionCoordinates.Latitude, positionCoordinates.Longitude, "AprsPosition"));
			}
		}

		public void OnAprsWeatherReport(string packetSender, WeatherInfo wi)
		{
			if (!currentTime.HasValue)
				return;

			string? wiComment = wi.Comment;
			int indexOf = wi.Comment.IndexOf(' ');
			wiComment = wiComment.Substring(indexOf + 1);
			if (wi.Position != null)
			{
				if (_storage.AprsPosition(currentTime.Value, packetSender, wi.Position.Coordinates, wiComment))
				{
					logger.Log(PluginLogLevel.Info, (String.Format("[{3}] {0} is at {1}, {2}", packetSender, wi.Position.Coordinates.Latitude, wi.Position.Coordinates.Longitude,"AprsPosition")));
				}
			}

			if (_storage.AprsWeatherReport(currentTime.Value, packetSender, wi))
			{
				logger.Log(PluginLogLevel.Info, (String.Format("[{2}] {0}, {1}", packetSender, currentTime.Value, "AprsWeather")));
			}
		}

		public void OnAprsChatMessage(string sender, string receiver, string message)
		{
			if (!currentTime.HasValue)
				return;

			_storage.AprsMessage(sender, currentTime.Value, receiver, message);
		}

		public void OnAprsStationCapabilities(string packetSender, StationCapabilities stationCapabilities)
		{
			if (!currentTime.HasValue)
				return;

			if (_storage.AprsStationCapabilities(packetSender, stationCapabilities))
			{
				logger.Log(PluginLogLevel.Info, (String.Format("[{2}] {0} -> {1}", packetSender, stationCapabilities.Encode(), "AprsStationCapabilities")));
			}
		}

		public void OnAprsGpsSentence(string packetSender, NmeaMessage parsed)
		{
			if (!currentTime.HasValue)
				return;
			GeoCoordinate geoCoordinate;
			
			switch (parsed.MessageType)
			{
				case "GPRMC":
					Rmc gprmc = (Rmc)parsed;
					geoCoordinate = new GeoCoordinate(gprmc.Latitude, gprmc.Longitude);
					bool conA = _storage.AprsPosition(currentTime.Value, packetSender, geoCoordinate, null);
					bool conB = _storage.AprsGpsSentence(currentTime.Value, packetSender, gprmc.Course, gprmc.MagneticVariation, gprmc.Speed);
					if (conA || conB)
					{
						logger.Log(PluginLogLevel.Info, (String.Format("[{2}] {0}: {1}", packetSender, parsed.ToString(), "AprsGpsSentence")));
					}
					break;
				default:
					throw new NotImplementedException(parsed.MessageType);
			}
		}

	}
}
