using skydiveLogs_api.Domain;
using skydiveLogs_api.DomainBusiness.Interfaces;
using skydiveLogs_api.DomainService.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;

namespace skydiveLogs_api.DomainBusiness
{
    public class GearService : IGearService
    {
        #region Public Constructors

        public GearService(IGearRepository gearRepository,
                           ICacheService cacheService,
                           IIdentityService identityService)
        {
            _gearRepository = gearRepository;
            _cacheService = cacheService;
            _identityService = identityService;
        }

        #endregion Public Constructors

        #region Public Methods

        /// <summary>
        /// Adds a new gear item to the system.
        /// </summary>
        /// <param name="newGear">The Gear entity containing the new gear data.</param>
        public void AddNewGear(Gear newGear)
        {
            newGear.User = _identityService.ConnectedUser;
            _gearRepository.Add(newGear);

            var userId = _identityService.ConnectedUser.Id;
            _cacheService.Delete(CacheType.Gear, userId: userId);
        }

        /// <summary>
        /// Adds rental gear to the system for a new user.
        /// </summary>
        /// <param name="newUser">The new user for whom rental gear should be added.</param>
        public void AddRentalGear(User newUser)
        {
            var rentalGear = new Gear
            {
                Name = "Rental gear",
                Manufacturer = "?",
                MainCanopy = "?",
                Aad = "Cypress/Vigil",
                MaxSize = 280,
                MinSize = 190,
                ReserveCanopy = "?",
                Equipment = "RAS",
                User = newUser
            };

            _gearRepository.Add(rentalGear);
        }

        /// <summary>
        /// Deletes a gear item by its ID.
        /// </summary>
        /// <param name="id">The gear ID to delete.</param>
        public void DeleteGearById(int id)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Retrieves all gear items.
        /// </summary>
        /// <returns>A collection of Gear entities containing all gear data.</returns>
        public IEnumerable<Gear> GetAllGears()
        {
            var userId = _identityService.ConnectedUser.Id;
            if (!_cacheService.Contains(CacheType.Gear, userId: userId))
                _cacheService.Put(CacheType.Gear,
                                  _gearRepository.GetAll(_identityService.ConnectedUser),
                                  5 * 60 * 1000,
                                  userId: userId);

            return _cacheService.Get<IEnumerable<Gear>>(CacheType.Gear, userId: userId);
        }

        /// <summary>
        /// Retrieves a gear item by its ID.
        /// </summary>
        /// <param name="id">The gear ID to retrieve.</param>
        /// <returns>A Gear entity containing the gear details.</returns>
        public Gear GetGearById(int id)
        {
            var allGears = GetAllGears();
            return allGears.Single(g => g.Id == id);
        }

        /// <summary>
        /// Updates an existing gear item.
        /// </summary>
        /// <param name="id">The gear ID to update.</param>
        /// <param name="gear">Gear entity containing the updated gear data.</param>
        /// <returns>True if the update was successful, false otherwise.</returns>
        public bool UpdateGear(int id, Gear gear)
        {
            gear.Id = id;
            gear.User = _identityService.ConnectedUser;

            return _gearRepository.Update(gear);
        }

        #endregion Public Methods

        #region Private Fields

        private readonly ICacheService _cacheService;
        private readonly IGearRepository _gearRepository;
        private readonly IIdentityService _identityService;

        #endregion Private Fields
    }
}
