using System;
using System.Threading.Tasks;
using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.Entity.SqlConnection;

namespace Valg.EVA.Skanning.Repositories.Transfers
{
    public class TransferWriteableRepository : ITransferWriteableRepository
    {
        private readonly ISqlConnectionFactory connectionFactory;

        public TransferWriteableRepository(ISqlConnectionFactory connectionFactory)
        {
            this.connectionFactory = connectionFactory;
        }

        public async Task<int> InsertTransferAsync(int transferJobId, TransferState state, string createdBy, byte[] dataPackage)
        {
            var result = await connectionFactory.SP_ExecuteAsync<int>("Transfer_Insert", new
            {
                TransferJobId = transferJobId,
                State = state.Id,
                UpdatedBy = createdBy,
                DataPackage = dataPackage
            }).ConfigureAwait(false);

            return result;
        }

        public async Task UpdateTransferStateAsync(TransferState transferState, DateTime lastUpdated, TransferState lastTransferState, int transferId, string updatedBy)
        {
            await connectionFactory.SP_ExecuteAsync("Transfer_UpdateTransferState", new
            {
                TransferState = transferState.Id,
                LastUpdated = lastUpdated,
                LastTransferState = lastTransferState.Id,
                TransferId = transferId,
                UpdatedBy = updatedBy
            }).ConfigureAwait(false);
        }

        public async Task SetTransferStateFailedAsync(int transferId, string errorCode, string updatedBy, DateTime? optionalConcurrencyToken)
        {
            await connectionFactory.SP_ExecuteAsync("Transfer_SetTransferStateFailed", new
            {
                TransferId = transferId,
                ErrorCode = errorCode,
                UpdatedBy = updatedBy,
                TransferStateId = TransferState.FileTransferFailed.Id,
                OptionalConcurrencyToken = optionalConcurrencyToken
            }).ConfigureAwait(false);
        }

        public async Task RefreshUpdatedTimestampOnTransfer(int transferId, string updatedBy, DateTime lastUpdated)
        {
            await connectionFactory.SP_ExecuteAsync("Transfer_RefreshUpdatedTimestampOnTransfer", new
            {
                TransferId = transferId,
                UpdatedBy = updatedBy,
                LastUpdated = lastUpdated,
                FileTransferFinishedState = TransferState.FileTransferFinished.Id,
                QueuedOnServerState = TransferState.QueuedOnServer.Id,
                StartedOnServerState = TransferState.StartedOnServer.Id
            }).ConfigureAwait(false);
        }

        public int InsertTransferJob(int countingId, string createdBy)
        {
            return (int)connectionFactory.SP_Execute<decimal>("TransferJob_Insert", new
            {
                CountingId = countingId,
                CreatedBy = createdBy
            });
        }

        public async Task SetTransferSuccessfulAsync(int transferId, string updatedBy, long fileId)
        {
            await connectionFactory.SP_ExecuteAsync("Transfer_SetTransferSuccessfull", new
            {
                TransferId = transferId,
                FileId = fileId,
                UpdatedBy = updatedBy,
                TransferStateId = TransferState.FileTransferFinished.Id
            }).ConfigureAwait(false);
        }
    }
}
