using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using UnivateProperties_API.Containers.Timeshare;
using UnivateProperties_API.Context;
using UnivateProperties_API.Model.Timeshare;

namespace UnivateProperties_API.Repository.Timeshare
{
    public class UnitConfigurationRepository : IRepository<UnitConfiguration>
    {
        private readonly DataContext _dbContext;

        public UnitConfigurationRepository(DataContext dbContext)
        {
            _dbContext = dbContext;
        }

        public List<UnitConfiguration> Get(Func<UnitConfiguration, bool> where)
        {
            return _dbContext.UnitConfigurations.Where(where).ToList();
        }

        public List<UnitConfigurationType> GetTypes(Func<UnitConfigurationType, bool> where)
        {
            return _dbContext.UnitConfigurationTypes.Where(where).ToList();
        }

        public List<UnitConfiguration> GetAll()
        {
            return _dbContext.UnitConfigurations.ToList();
        }

        public UnitConfiguration GetDetailed(Func<UnitConfiguration, bool> first)
        {
            var item = _dbContext.UnitConfigurations.FirstOrDefault(first);
            item.Types = GetTypes(t => t.UnitConfigurationId == item.Id);
            return item;
        }

        public List<UnitConfigurationDto> GetMyDetailed()
        {
            var list = new List<UnitConfigurationDto>();
            UnitConfigurationDto dto = new UnitConfigurationDto();

            foreach (var item in GetAll())
            {
                dto = new UnitConfigurationDto()
                {
                    Id = item.Id,
                    Code = item.Code,
                    Bedrooms = item.Bedrooms,
                    Adults = item.Adults,
                    Children = item.Children
                };
                dto.Types = new List<string>();
                foreach (var subItem in GetTypes(t => t.UnitConfigurationId == item.Id))
                {
                    dto.Types.Add(subItem.Description);
                }
                list.Add(dto);
            }
            return list;
        }

        public List<UnitConfiguration> GetDetailedAll()
        {
            var list = new List<UnitConfiguration>();
            foreach(var item in GetAll())
            {
                item.Types = GetTypes(t => t.UnitConfigurationId == item.Id);
                list.Add(item);
            }
            return list;
        }

        public void Insert(UnitConfiguration item)
        {
            item.Id = NewId();
            _dbContext.Add(item);
            Save();
        }

        public void InsertType(UnitConfigurationType type)
        {
            int id = _dbContext.UnitConfigurationTypes.Max(x => x.Id);
            type.Id = id + 1;
            _dbContext.Add(type);
            Save();
        }

        public void Insert(IEnumerable<UnitConfiguration> items)
        {
            int id = NewId();
            foreach (var item in items)
            {
                item.Id = id;
                _dbContext.Add(item);
                id += 1;
            }
            Save();
        }

        public void Remove(UnitConfiguration item)
        {
            var i = _dbContext.UnitConfigurations.Find(item);
            _dbContext.UnitConfigurations.Remove(i);
            Save();
        }

        public void RemoveType(UnitConfigurationType item)
        {
            var i = _dbContext.UnitConfigurationTypes.Find(item);
            _dbContext.UnitConfigurationTypes.Remove(i);
            Save();
        }

        public void Remove(IEnumerable<UnitConfiguration> items)
        {
            foreach (var item in items)
            {
                var i = _dbContext.UnitConfigurations.Find(item);
                _dbContext.UnitConfigurations.Remove(i);
            }
            Save();
        }

        public void RemoveAtId(int item)
        {
            var i = _dbContext.UnitConfigurations.Find(item);
            _dbContext.UnitConfigurations.Remove(i);
            Save();
        }

        public void Save()
        {
            _dbContext.SaveChanges();
        }

        public void Update(UnitConfiguration item)
        {
            _dbContext.Entry(item).State = EntityState.Modified;
            Save();
        }

        public int NewId()
        {
            int id = 0;
            if (_dbContext.UnitConfigurations.Count() > 0)
            {
                id = _dbContext.UnitConfigurations.Max(x => x.Id);
            }
            id += 1;
            return id;
        }
    }
}