using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using AutoMapper;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.ViewModels.ServiceReminder;

namespace MileageTraker.Web.ViewModels.VehicleService
{
	public class UpdateServiceRemindersViewModel : IValidatableObject
	{
		[Display(Name = "Existing Reminders")]
		public CheckBoxViewModel DeleteServiceReminders { get; set; }

		[HiddenInput(DisplayValue = false)]
		public int? ServiceReminderId { get; set; }

		[HiddenInput(DisplayValue = false)]
		[Required]
		[Remote("Exists", "Vehicle", ErrorMessage = "ID not found")]
		[StringLength(6, MinimumLength = 4, ErrorMessage = "Must be at least a 4 digit number")]
		[Display(Name = "Vehicle ID")]
		[RegularExpression(@"\d+", ErrorMessage = "Vehicle ID must be all numbers")]
		[InputSize("mini")]
		public string VehicleId { get; set; }

		[HiddenInput(DisplayValue = false)]
		public int? CurrentOdometer { get; set; }

		[InputSize("small")]
		[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
		public int? TargetOdometer { get; set; }

		[StringLength(64)]
		public string Description { get; set; }

		static UpdateServiceRemindersViewModel()
		{
			Mapper.CreateMap<UpdateServiceRemindersViewModel, Models.ServiceReminder>();
		}

		public Models.ServiceReminder GetServiceReminder()
		{
			if (!TargetOdometer.HasValue || TargetOdometer.Value == 0)
				return null;
			var serviceReminder = new Models.ServiceReminder();
			Mapper.Map(this, serviceReminder);
			return serviceReminder;
		}

		public static string FormatServiceReminder(Models.ServiceReminder serviceReminder)
		{
			var s = "Target ODO: " + serviceReminder.TargetOdometer;
			if (!string.IsNullOrEmpty(serviceReminder.Description))
				s += " Description: " + serviceReminder.Description;
			return s;
		}

		public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
		{
			if (!TargetOdometer.HasValue) yield break;

			using (var dataService = new DataService())
			{
				var duplicateServiceReminder = dataService.FindDuplicateServiceReminder(VehicleId, TargetOdometer.Value, Description);

				if (duplicateServiceReminder != null)
					yield return new ValidationResult("Exact duplicate of this reminder already exists");

				var vehicle = dataService.GetVehicle(VehicleId);

				if (vehicle.InactiveDate.HasValue)
					yield return new ValidationResult("Vehicle is inactive, no service reminder permitted");

				// no reminders for mileage less than the current odometer
				if (vehicle.CurrentOdometer.HasValue && TargetOdometer <= vehicle.CurrentOdometer)
					yield return new ValidationResult(
						string.Format("Target odometer {0} must be greater than current odometer {1}",
						              TargetOdometer, vehicle.CurrentOdometer.Value), new[] {"TargetOdometer"});
			}
		}
	}
}