using BankContracts.BindingModels;
using BankContracts.ViewModels;
using BankDataModels;
using System.ComponentModel.DataAnnotations;
using BankDataModels.ProxyModels;

namespace BankDatabaseImplement.Models
{
    public class Cost : ICostModel
    {
        [Required]
        public int EmployeeId { get; private set; }
        [Required]
        public string NameOfCost { get; private set; } = string.Empty;
        public int Id { get; private set; }
        [Required]
        public double Price { get; private set; }
        private Dictionary<int, CostByPurchaseModel>? _cachedPurchases;
        public Dictionary<int, CostByPurchaseModel> PurchasesModels => _cachedPurchases ??= Purchases.Select(x => (CostByPurchaseModel)x).ToDictionary(x => x.PurchaseId, x => x);
        [Required]
        public Employee? Employee { get; private set; }
        [Required]
        public List<CostByPurchase> Purchases { get; private set; } = new();

        public static Cost Create(CostBindingModel model)
        {
            if (model == null)
            {
                return null;
            }
            return new Cost()
            {
                EmployeeId = model.EmployeeId,
                NameOfCost = model.NameOfCost,
                Price = model.Price,
                //PurchasesModels = model.PurchasesModels,
                Id = model.Id
            };
        }

        public CostViewModel GetViewModel => new()
        {
            PhoneNumber = Employee?.PhoneNumber ?? string.Empty,
            PurchaseModels = PurchasesModels,
            EmployeeId = EmployeeId,
            NameOfCost = NameOfCost,
            Price = Price,
            Id = Id
        };

        public void Update(CostBindingModel model)
        {
            NameOfCost = model.NameOfCost;
            Price = model.Price;
        }

        /// <summary>
        /// Привязка статей затрат к покупкам
        /// </summary>
        public void UpdatePurchases(BankDB context, CostBindingModel model)
        {
            var oldPurchases = context.CostByPurchases.Where(x => x.CostId == model.Id).ToDictionary(x => x.PurchaseId, x => x);
            var newPurchases = model.PurchasesModels.ToDictionary(
                x => x.Key,
                x => new CostByPurchase()
                {
                    CostId = model.Id,
                    PurchaseId = x.Key,
                    Count = x.Value.Count,
                }
            );
            context.RemoveRange(oldPurchases.Where(x => !newPurchases.ContainsKey(x.Key)).Select(x => x.Value));
            context.AddRange(newPurchases.Where(x => !oldPurchases.ContainsKey(x.Key)).Select(x => x.Value));
            oldPurchases.Where(x => newPurchases.ContainsKey(x.Key))
                .Select(x => x.Value).ToList()
                .ForEach(x => x.Count = newPurchases[x.PurchaseId].Count);
            context.SaveChanges();
            _cachedPurchases = null;
        }
    }
}
