using GreenTree.Nachtragsmanagement.Services.Configuration;
using GreenTree.Nachtragsmanagement.Web.Models.Admin.User;
using GreenTree.Nachtragsmanagement.Web.Models.Appendix;
using GreenTree.Nachtragsmanagement.Web.Models.Deviation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GreenTree.Nachtragsmanagement.Web.Models.Site
{
    public class SiteDataModel
    {
        public int Id { get; set; }
        public string CustomNumber { get; set; }
        public string Description { get; set; }
        public DateTime? Start { get; set; }
        public DateTime? End { get; set; }
        public string Finished { get; set; }
        public string Comment { get; set; }
        public ICollection<int> DeviationValues { get; set; }
        public ICollection<string> DeviationDescriptions { get; set; }
        public ICollection<DeviationDataModel> Deviations { get; set; }
        public string DeviationDescription
        {
            get
            {
                if (DeviationDescriptions == null)
                    return String.Empty;
                else
                    return String.Join(" - ", DeviationDescriptions);
            }
        }
        public string HtmlDeviationDescription
        {
            get
            {
                if (DeviationDescriptions == null)
                    return String.Empty;
                else
                    return String.Join("</br>--------------</br>", 
                        Deviations
                            .Select(d => String.Format("{0} - {1}", d.CustomNumber, d.Description)));
            }
        }
        public decimal? DeviationValue { get; set; }
        public decimal? SiteDeviationValue { get; set; }
        public ICollection<int> AppendixValues { get; set; }
        public ICollection<string> AppendixDescriptions { get; set; }
        public ICollection<AppendixDataModel> Appendices { get; set; }
        public string AppendixDescription
        {
            get
            {
                if (AppendixDescriptions == null)
                    return String.Empty;
                else
                    return String.Join(", ", AppendixDescriptions);
            }
        }
        public decimal? AppendixValueRemaining { get; set; }
        public decimal? AppendixValueNegotiated { get; set; }
        public ICollection<int> UserValues { get; set; }
        public ICollection<string> UserDescriptions { get; set; }
        public ICollection<UserDataModel> Users { get; set; }
        public string UserDescription { get; set; }
        public ICollection<SiteTreeDataModel> SiteTreeData { get; set; }

        public SiteDataModel()
        {
            DeviationValues = new List<int>();
            DeviationDescriptions = new List<string>();

            AppendixValues = new List<int>();
            AppendixDescriptions = new List<string>();

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

        public static SiteDataModel FromSite(Core.Domain.Site.Site siteEntity, bool newWhenIsNull, 
            IConfigurationService configurationService)
        {
            if (siteEntity == null && newWhenIsNull)
                return new SiteDataModel
                {
                    Id = -1,
                };

            if (siteEntity == null && !newWhenIsNull)
                throw new ArgumentNullException("siteEntity", "Cannot create SiteDataModel from NULL site entity.");

            var remainingAppendixStatuses = configurationService.TryGetConfigItemValue<int[]>(
                "GreenTree.Nachtragsmanagement.SiteGrid.RemainingAppendixStatuses", new[] { 1, 5, 6, 7, 11, 12, 13 });

            return new SiteDataModel
            {
                Id = siteEntity.Id,
                CustomNumber = siteEntity.CustomNumber,
                Description = siteEntity.Description,
                Start = siteEntity.Start,
                End = siteEntity.End,
                Finished = siteEntity.End.HasValue
                    ? siteEntity.End <= DateTime.Now
                        ? "Ja"
                        : "Nein"
                    : "Nein",
                Comment = siteEntity.Comment,
                DeviationValues =
                    siteEntity.Deviations
                        .Select(r => r.Id)
                        .ToList(),
                DeviationDescriptions =
                    siteEntity.Deviations
                        .Select(r => r.Description)
                        .ToList(),
                Deviations = 
                    siteEntity.Deviations
                        .Select(r => DeviationDataModel.FromDeviation(r, false, configurationService))
                        .ToList(),
                DeviationValue = 
                    siteEntity.Deviations
                        .Sum(r => r.Value.HasValue && r.Percentage.HasValue
                            ? r.Value * r.Percentage.Value
                            : 0) +
                    siteEntity.Appendices
                        .SelectMany(r => r.Deviations)
                            .Sum(r => r.Value.HasValue && r.Percentage.HasValue
                                ? r.Value * r.Percentage.Value
                                : 0),
                SiteDeviationValue =
                    siteEntity.Deviations
                        .Sum(r => r.Value.HasValue && r.Percentage.HasValue
                            ? r.Value * r.Percentage.Value
                            : 0),
                AppendixValues =
                    siteEntity.Appendices
                        .Select(r => r.Id)
                        .ToList(),
                AppendixDescriptions =
                    siteEntity.Appendices
                        .Select(r => r.CustomNumber)
                        .ToList(),
                Appendices = 
                    siteEntity.Appendices
                        .Select(r => AppendixDataModel.FromAppendix(r, false))
                        .ToList(),
                UserValues =
                    siteEntity.Users
                        .Select(r => r.Id)
                        .ToList(),
                UserDescriptions =
                    siteEntity.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(),
                AppendixValueRemaining =
                    siteEntity.Appendices
                        .Where(r => remainingAppendixStatuses.Contains(r.StateId ?? 0))
                        .Sum(r => 
                            r.Value.HasValue && r.Percentage.HasValue
                                ? r.Value.Value * r.Percentage.Value
                                : 0),
                AppendixValueNegotiated =
                    siteEntity.Appendices
                        .Where(r => !remainingAppendixStatuses.Contains(r.StateId ?? 0))
                        .Sum(r =>
                            r.Value.HasValue && r.Percentage.HasValue
                                ? r.Value.Value * r.Percentage.Value
                                : 0),
                UserDescription =
                    String.Join(", ",
                        siteEntity.Users
                            .Select(r => new
                            {
                                LastName = r.Lastname,
                                Roles = String.Join(", ", r.Roles.Select(u => u.Description))
                            })
                            .Select(u => String.Format("{0} ({1})", u.LastName, u.Roles ))),
                Users = 
                    siteEntity.Users
                        .Select(r => UserDataModel.FromUser(r, false))
                        .ToList(),
            };
        }

        public Core.Domain.Site.Site ToSite()
        {
            return new Core.Domain.Site.Site
            {
                Id = this.Id,
                CustomNumber = this.CustomNumber,
                Description = Description,
                Comment = this.Comment,
                Start = this.Start,
                End = this.End
            };
        }
    }
}