using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GreenTree.Nachtragsmanagement.Core.Data;
using GreenTree.Nachtragsmanagement.Core.Domain.Appendix;
using GreenTree.Nachtragsmanagement.Core.Domain.Invoice;

namespace GreenTree.Nachtragsmanagement.Services.Appendix
{
    public class AppendixService : IAppendixService
    {
        #region Fields

        private readonly IRepository<Core.Domain.Appendix.Appendix> _appendixRepository;
        private readonly IRepository<Category> _categoryRepository;
        private readonly IRepository<Invoice> _invoiceRepository;
        private readonly IRepository<State> _stateRepository;

        #endregion

        #region Ctor

        /// <summary>
        /// Initializes a new instance of the AppendixService class
        /// </summary>
        public AppendixService(
            IRepository<Core.Domain.Appendix.Appendix> appendixRepository,
            IRepository<Category> categoryRepository,
            IRepository<Invoice> invoiceRepository,
            IRepository<State> stateRepository)
        {
            _appendixRepository = appendixRepository;
            _categoryRepository = categoryRepository;
            _invoiceRepository = invoiceRepository;
            _stateRepository = stateRepository;
        }

        #endregion

        #region Appendix

        /// <summary>
        /// Gets all appendices
        /// </summary>
        public IList<Core.Domain.Appendix.Appendix> GetAllAppendices()
        {
            return _appendixRepository.Table.ToList();
        }

        /// <summary>
        /// Gets all appendices where the user is assigned to the corresponding site if the current role only allows assigned sites
        /// </summary>
        public IList<Core.Domain.Appendix.Appendix> GetAllUserAssignedAppendices(Core.Domain.User.User user)
        {
            if (user == null || (user != null && user.CurrentRole == null))
                return new List<Core.Domain.Appendix.Appendix>();

            if (user.CurrentRole.SeeOnlyAssigned)
            {
                return
                    _appendixRepository.Table
                        .Where(a => a.Site != null && a.Site.Users
                            .Select(u => u.Id).Contains(user.Id))
                        .ToList();
            }
            else
                return GetAllAppendices();

        }

        /// <summary>
        /// Gets a appendix by specified Id
        /// </summary>
        /// <param name="id">Appendix identifier.</param>
        public Core.Domain.Appendix.Appendix GetAppendixById(int id)
        {
            return _appendixRepository.GetById(id);
        }

        /// <summary>
        /// Gets all appendices to the specified ids
        /// </summary>
        public IList<Core.Domain.Appendix.Appendix> GetAppendicesByIds(int[] ids)
        {
            return _appendixRepository.Table
                .Where(u => ids.Contains(u.Id))
                .ToList();
        }

        /// <summary>
        /// Gets a appendix by specified custom number
        /// </summary>
        /// <param name="customNumber">Customer number.</param>
        public Core.Domain.Appendix.Appendix GetAppendixByCustomNumber(string customNumber)
        {
            return _appendixRepository
                .Table.FirstOrDefault(u => u.CustomNumber == customNumber);
        }

        /// <summary>
        /// Insert a appendix
        /// </summary>
        /// <param name="appendix">Appendix.</param>
        public void InsertAppendix(Core.Domain.Appendix.Appendix appendix)
        {
            _appendixRepository.Insert(appendix);
        }

        /// <summary>
        /// Update a appendix
        /// </summary>
        /// <param name="appendix">Appendix.</param>
        public void UpdateAppendix(Core.Domain.Appendix.Appendix appendix)
        {
            _appendixRepository.Update(appendix);
        }

        /// <summary>
        /// Delete a appendix
        /// </summary>
        /// <param name="appendix">Appendix.</param>
        public void DeleteAppendix(Core.Domain.Appendix.Appendix appendix)
        {
            _appendixRepository.Delete(appendix);
        }

        #endregion

        #region Category

        /// <summary>
        /// Gets all categories
        /// </summary>
        public IList<Category> GetAllCategories()
        {
            return _categoryRepository.Table.ToList();
        }

        /// <summary>
        /// Gets a category by specified Id
        /// </summary>
        /// <param name="id">Category identifier.</param>
        public Category GetCategoryById(int id)
        {
            return _categoryRepository.GetById(id);
        }

        /// <summary>
        /// Gets all categories to the specified ids
        /// </summary>
        public IList<Category> GetCategoriesByIds(int[] ids)
        {
            return _categoryRepository.Table
                .Where(r => ids.Contains(r.Id))
                .ToList();
        }

        /// <summary>
        /// Insert a appendix
        /// </summary>
        /// <param name="category">Category.</param>
        public void InsertCategory(Category category)
        {
            _categoryRepository.Insert(category);
        }

        /// <summary>
        /// Update a category
        /// </summary>
        /// <param name="category">Category.</param>
        public void UpdateCategory(Category category)
        {
            _categoryRepository.Update(category);
        }

        /// <summary>
        /// Delete a category
        /// </summary>
        /// <param name="category">Category.</param>
        public void DeleteCategory(Category category)
        {
            _categoryRepository.Delete(category);
        }

        #endregion

        #region Invoice

        /// <summary>
        /// Gets all invoices
        /// </summary>
        public IList<Invoice> GetAllInvoices()
        {
            return _invoiceRepository.Table.ToList();
        }

        /// <summary>
        /// Gets a invoice by specified Id
        /// </summary>
        /// <param name="id">Invoice identifier.</param>
        public Invoice GetInvoiceById(int id)
        {
            return _invoiceRepository.GetById(id);
        }

        /// <summary>
        /// Gets all invoices to the specified ids
        /// </summary>
        public IList<Invoice> GetInvoicesByIds(int[] ids)
        {
            return _invoiceRepository.Table
                .Where(r => ids.Contains(r.Id))
                .ToList();
        }

        /// <summary>
        /// Insert a appendix
        /// </summary>
        /// <param name="invoice">Invoice.</param>
        public void InsertInvoice(Invoice invoice)
        {
            _invoiceRepository.Insert(invoice);
        }

        /// <summary>
        /// Update a invoice
        /// </summary>
        /// <param name="invoice">Invoice.</param>
        public void UpdateInvoice(Invoice invoice)
        {
            _invoiceRepository.Update(invoice);
        }

        /// <summary>
        /// Delete a invoice
        /// </summary>
        /// <param name="invoice">Invoice.</param>
        public void DeleteInvoice(Invoice invoice)
        {
            _invoiceRepository.Delete(invoice);
        }

        #endregion

        #region State

        /// <summary>
        /// Gets all states
        /// </summary>
        public IList<State> GetAllStates()
        {
            return _stateRepository.Table.ToList();
        }

        /// <summary>
        /// Gets a state by specified Id
        /// </summary>
        /// <param name="id">State identifier.</param>
        public State GetStateById(int id)
        {
            return _stateRepository.GetById(id);
        }

        /// <summary>
        /// Gets all states to the specified ids
        /// </summary>
        public IList<State> GetStatesByIds(int[] ids)
        {
            return _stateRepository.Table
                .Where(r => ids.Contains(r.Id))
                .ToList();
        }

        /// <summary>
        /// Gets all appendices to the specified with the specified status id
        /// </summary>
        /// <param name="id">State identifier.</param>
        public IList<Core.Domain.Appendix.Appendix> GetAppendicesByState(int id)
        {
            return _appendixRepository.Table
                .Where(d => d.StateId == id)
                .ToList();
        }

        /// <summary>
        /// Gets the state which is defaultly selected
        /// </summary>
        public State GetDefaultState()
        {
            return _stateRepository.Table
                .FirstOrDefault(s => s.IsDefault);
        }

        /// <summary>
        /// Gets the state which is marked as finish
        /// </summary>
        public State GetFinishState()
        {
            return _stateRepository.Table
                .FirstOrDefault(s => s.IsFinish);
        }

        /// <summary>
        /// Insert a appendix
        /// </summary>
        /// <param name="state">State.</param>
        public void InsertState(State state)
        {
            _stateRepository.Insert(state);
        }

        /// <summary>
        /// Update a state
        /// </summary>
        /// <param name="state">State.</param>
        public void UpdateState(State state)
        {
            _stateRepository.Update(state);
        }

        /// <summary>
        /// Delete a state
        /// </summary>
        /// <param name="state">State.</param>
        public void DeleteState(State state)
        {
            _stateRepository.Delete(state);
        }

        #endregion
    }
}