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

namespace skydiveLogs_api.DomainBusiness
{
    public class JumpService : IJumpService
    {
        #region Public Constructors

        public JumpService(IJumpTypeService jumpTypeService,
                           IAircraftService aircraftService,
                           IDropZoneService dropZoneService,
                           IGearService gearService,
                           IJumpRepository jumpRepository,
                           IIdentityService identityService)
        {
            _jumpTypeService = jumpTypeService;
            _aircraftService = aircraftService;
            _dropZoneService = dropZoneService;
            _gearService = gearService;
            _jumpRepository = jumpRepository;
            _identityService = identityService;
        }

        #endregion Public Constructors

        #region Public Methods

        /// <summary>
        /// Adds a new jump to the system.
        /// </summary>
        /// <param name="aircraftId">The ID of the aircraft to use for this jump.</param>
        /// <param name="dzId">The ID of the drop zone for this jump.</param>
        /// <param name="jumpTypeId">The ID of the jump type for this jump.</param>
        /// <param name="gearId">The ID of the gear for this jump.</param>
        /// <param name="jump">Jump entity containing the new jump data.</param>
        public void AddNewJump(int aircraftId,
                               int dzId,
                               int jumpTypeId,
                               int gearId,
                               Jump jump)
        {
            var selectedGear = _gearService.GetGearById(gearId);
            var selectedJumpType = _jumpTypeService.GetJumpTypeById(jumpTypeId);
            var selectedAircraft = _aircraftService.GetAircraftById(aircraftId);
            var selectedDropZone = _dropZoneService.GetDzById(dzId);

            jump.Aircraft = selectedAircraft;
            jump.JumpType = selectedJumpType;
            jump.DropZone = selectedDropZone;
            jump.Gear = selectedGear;
            jump.User = _identityService.ConnectedUser;

            _jumpRepository.Add(jump);
        }

        /// <summary>
        /// Deletes a jump by its ID.
        /// </summary>
        /// <param name="id">The jump ID to delete.</param>
        public void DeleteJumpById(int id)
        {
            _jumpRepository.DeleteById(id);
        }

        /// <summary>
        /// Retrieves all jumps for the current user.
        /// </summary>
        /// <returns>A collection of Jump entities containing all jumps.</returns>
        public IEnumerable<Jump> GetAllJumps()
        {
            return _jumpRepository.GetAll(_identityService.ConnectedUser);
        }

        /// <summary>
        /// Retrieves a jump by its ID.
        /// </summary>
        /// <param name="id">The jump ID to retrieve.</param>
        /// <returns>A Jump entity containing the jump details.</returns>
        public Jump GetJumpById(int id)
        {
            return _jumpRepository.GetById(id);
        }

        /// <summary>
        /// Retrieves the total count of jumps for the current user.
        /// </summary>
        /// <returns>The total number of jumps.</returns>
        public int GetJumpCount()
        {
            return _jumpRepository.GetCount(_identityService.ConnectedUser);
        }

        /// <summary>
        /// Retrieves a range of jumps for the current user with pagination.
        /// </summary>
        /// <param name="beginIndex">The starting index for pagination.</param>
        /// <param name="endIndex">The ending index for pagination.</param>
        /// <returns>A collection of Jump entities containing the requested range.</returns>
        public IEnumerable<Jump> GetJumpsByIndexes(int beginIndex, int endIndex)
        {
            return _jumpRepository.GetBetweenIndex(_identityService.ConnectedUser, beginIndex, endIndex);
        }

        /// <summary>
        /// Updates an existing jump.
        /// </summary>
        /// <param name="id">The jump ID to update.</param>
        /// <param name="updatedJump">Jump entity containing the updated jump data.</param>
        public void UpdateJump(int id, Jump updatedJump)
        {
            var myJump = GetJumpById(id);
            myJump.IsSpecial = updatedJump.IsSpecial;
            myJump.WithCutaway = updatedJump.WithCutaway;
            myJump.Notes = updatedJump.Notes;

            _jumpRepository.Update(myJump);
        }

        #endregion Public Methods

        #region Private Fields

        private readonly IAircraftService _aircraftService;
        private readonly IDropZoneService _dropZoneService;
        private readonly IGearService _gearService;
        private readonly IIdentityService _identityService;
        private readonly IJumpRepository _jumpRepository;
        private readonly IJumpTypeService _jumpTypeService;

        #endregion Private Fields
    }
}
