using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TransportGuideContracts.BindingModels;
using TransportGuideContracts.ViewModels;
using TransportGuideDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace TransportGuideDatabaseImplements.Models
{
	public class Route : IRouteModel
	{
		public int Id { get; private set; }

		public int TransportTypeId { get; private set; }		

		[Required]
		public string Name { get; private set; } = string.Empty;

		[Required]
		public string IP { get; private set; } = string.Empty;


		Dictionary<int, (IStopModel, int)>? _stopRoutes = null;

		public virtual TransportType TransportType { get; set; }


		[NotMapped]
		public Dictionary<int, (IStopModel, int)> StopRoutes { 
			get
			{
				if (_stopRoutes == null)
				{
					_stopRoutes = Stops.ToDictionary(recPC => recPC.StopId, recPC => (recPC.Stop as IStopModel, recPC.Nomer));
				}
				return _stopRoutes;
			} 
				
		}

		[ForeignKey("RouteId")]
		public virtual List<StopRoute> Stops { get; set; } = new();

		public static Route Create(TransportGuideDB context, RouteBindingModel model)
		{
			return new Route()
			{
				Id = model.Id,
				Name = model.Name,
				IP = model.IP,
				Stops = model.StopRoutes.Select(x => new StopRoute
				{
					Stop = context.Stops.First(y => y.Id == x.Key),
					Nomer = x.Value.Item2
				}).ToList()
			};
		}

		public void Update(RouteBindingModel model)
		{
			Name = model.Name;
			IP = model.IP;
		}

		public RouteViewModel GetViewModel
		{
			get
			{
				using var context = new TransportGuideDB();
				return new RouteViewModel
				{
					Id = Id,
					TransportTypeId = TransportTypeId,
					IP = IP,
					Name = Name,
					TransportTypeName = context.TransportTypes.FirstOrDefault(x => x.Id == TransportTypeId)?.Name ?? string.Empty,
				};
			}
		}

		public void UpdateStops(TransportGuideDB context, RouteBindingModel model)
		{
			var routeStops = context.StopRoutes.Where(rec => rec.RouteId == model.Id).ToList();

			if (routeStops != null && routeStops.Count > 0)
			{ // удалили те, которых нет в модели
				context.StopRoutes.RemoveRange(routeStops.Where(rec => !model.StopRoutes.ContainsKey(rec.StopId)));
				context.SaveChanges();
				// обновили количество у существующих записей
				foreach (var updateStop in routeStops)
				{
					updateStop.Nomer = model.StopRoutes[updateStop.StopId].Item2;
					model.StopRoutes.Remove(updateStop.StopId);
				}
				context.SaveChanges();
			}

			var route = context.Routes.First(x => x.Id == Id);

			foreach (var pc in model.StopRoutes)
			{
				context.StopRoutes.Add(new StopRoute
				{
					Route = route,
					Stop = context.Stops.First(x => x.Id == pc.Key),
					Nomer = pc.Value.Item2
				});
				context.SaveChanges();
			}
			_stopRoutes = null;
		}

	}
}