using GreenTree.Nachtragsmanagement.Core.Plugins;
using GreenTree.Nachtragsmanagement.Services.Misc;
using GreenTree.Nachtragsmanagement.Services.Scheduling;
using GreenTree.Nachtragsmanagement.Web.Models.Admin.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GreenTree.Nachtragsmanagement.Web.Models.Misc
{
    public class MailNotificationDataModel
    {
        public int Id { get; set; }
        public string CronExpression { get; set; }
        public string CronExpressionDescription { get; set; }
        public string NextExecutionTime { get; set; }
        public INotificationPlugin NotificationPlugin { get; set; }
        public string NotificationPluginSystemName { get; set; }
        public string NotificationPluginSystemNameDescription { get; set; }
        public string NotificationJobSystemName { get; set; }
        public string NotificationJobSystemNameDescription { get; set; }
        public ICollection<int> UserValues { get; set; }
        public ICollection<string> UserDescriptions { get; set; }
        public ICollection<UserDataModel> Users { get; set; }
        public string UserDescription
        {
            get
            {
                if (UserDescriptions == null)
                    return String.Empty;
                else
                    return String.Join(", ", UserDescriptions);
            }
        }

        public MailNotificationDataModel()
        {
            UserValues = new List<int>();
            UserDescriptions = new List<string>();
        }

        public static MailNotificationDataModel FromMailNotification(Core.Domain.Misc.MailNotification mailNotificationEntity, 
            bool newWhenIsNull, INotificationService service, INotificationScheduler scheduler)
        {
            if (mailNotificationEntity == null && newWhenIsNull)
                return new MailNotificationDataModel
                {
                    Id = -1,
                };

            if (mailNotificationEntity == null && !newWhenIsNull)
                throw new ArgumentNullException("mailNotificationEntity", "Cannot create MailNotificationDataModel from NULL mailNotification entity.");

            var notificationPlugin = service.GetNotificationPlugin(mailNotificationEntity.NotificationPluginSystemName);
            var nextExecutionTime = scheduler.GetNextExecutionOfJob(mailNotificationEntity);

            var notificationDataModel = new MailNotificationDataModel
            {
                Id = mailNotificationEntity.Id,
                CronExpression = mailNotificationEntity.CronExpression,
                CronExpressionDescription = 
                    CronExpressionDescriptor.ExpressionDescriptor.GetDescription(
                        mailNotificationEntity.CronExpression, 
                        new CronExpressionDescriptor.Options { Locale = "de" } ),
                NextExecutionTime = nextExecutionTime == DateTime.MinValue
                    ? String.Empty
                    : nextExecutionTime.ToString("dd.MM.yyyy - HH:mm \"Uhr\""),
                NotificationPlugin = notificationPlugin,
                NotificationPluginSystemName = mailNotificationEntity.NotificationPluginSystemName,
                NotificationJobSystemName = mailNotificationEntity.NotificationJobSystemName,
                UserValues =
                    mailNotificationEntity.Users
                        .Select(r => r.Id)
                        .ToList(),
                UserDescriptions =
                    mailNotificationEntity.Users
                        .Select(r => new
                        {
                            LastName = r.Lastname,
                            Roles = String.Join(", ", r.Roles.Select(u => u.Description))
                        })
                        .OrderBy(r => r.Roles)
                        .Select(r => String.Format("{0}|({1})", r.LastName, r.Roles))
                        .ToList(),
                Users =
                    mailNotificationEntity.Users
                        .Select(r => UserDataModel.FromUser(r, false))
                        .ToList(),
            };

            notificationDataModel.NotificationPluginSystemNameDescription =
                    notificationPlugin == null
                        ? String.Empty
                        : notificationPlugin.Name;

            notificationDataModel.NotificationJobSystemNameDescription =
                    notificationPlugin == null
                        ? String.Empty
                        : notificationPlugin.AvailableNotificationJobs
                            .Any(j => j.SystemName == notificationDataModel.NotificationJobSystemName)
                                ? notificationPlugin.AvailableNotificationJobs
                                    .First(j => j.SystemName == notificationDataModel.NotificationJobSystemName).Name
                                : String.Empty;

            return notificationDataModel;
        }

        public Core.Domain.Misc.MailNotification ToMailNotification()
        {
            return new Core.Domain.Misc.MailNotification
            {
                Id = this.Id,
                CronExpression = this.CronExpression,
                NotificationPluginSystemName = this.NotificationPluginSystemName,
                NotificationJobSystemName = this.NotificationJobSystemName
            };
        }
    }
}