namespace Hims.Infrastructure.Services
{
    using System;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Shared.EntityModels;
    using Dapper;

    /// <inheritdoc />
    public class ExcelUploadHistoryServices : IExcelUploadHistoryService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <inheritdoc cref="IExcelUploadHistoryService" />
        public ExcelUploadHistoryServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public async Task<int> ModifyExcelUploadAsync(ExcelUploadHistoryModel model)
        {
            var upload = new ExcelUploadHistory
            {
                AddedProducts = model.AddedProducts,
                CreatedDate = DateTime.UtcNow.AddMinutes(330),
                SheetName = model.SheetName,
                SheetType = model.SheetType,
                TypeOf = model.TypeOf,
                UploadedBy = model.UploadedBy,
                ProductStatus = model.ProductStatus,
                LocationId = model.LocationId
            };
            if (model.ExcelUploadHistoryId == 0)
            {
                return await this.unitOfWork.ExcelUploadHistory.InsertAsync(upload);
            }
            else
            {
                var previousRecord = await this.unitOfWork.ExcelUploadHistory.FindAsync(m => m.ExcelUploadHistoryId == model.ExcelUploadHistoryId);
                var completeProductList = previousRecord.AddedProducts + "," + upload.AddedProducts;
                var completeProductStatus = previousRecord.ProductStatus + "," + upload.ProductStatus;
                previousRecord.AddedProducts = completeProductList;
                previousRecord.ProductStatus = completeProductStatus;
                await this.unitOfWork.ExcelUploadHistory.UpdateAsync(previousRecord);
                return previousRecord.ExcelUploadHistoryId;

            }
        }

        /// <inheritdoc />
        public async Task<IEnumerable<ExcelUploadHistoryModel>> FetchAllAsync(ExcelUploadHistoryModel model)
        {
            var where = "where 1=1 ";

            if (!string.IsNullOrEmpty(model.TypeOf))
            {
                where += $@" and EUH.""TypeOf"" ='{model.TypeOf}'";
            }

            var query = $@" Select count(EUH.*) over() as ""TotalItems"",EUH.*, A.""FullName"" as ""UploadedByName"", l.""Name"" as ""LocationName"" from ""ExcelUploadHistory"" EUH 
                            join ""Account"" A on A.""AccountId"" = EUH.""UploadedBy""
                            left join ""Location"" l on l.""LocationId"" = EUH.""LocationId""
                            {where}
                            order by ""CreatedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<ExcelUploadHistoryModel>(query);
        }

        /// <inheritdoc />
        public async Task<ExcelUploadHistoryModel> GetSingleExcelHistory(int excelUploadHistoryId)
        {
            var data = await this.unitOfWork.ExcelUploadHistory.FindAsync(m => m.ExcelUploadHistoryId == excelUploadHistoryId);
            return new ExcelUploadHistoryModel
            {
                AddedProducts = data.AddedProducts,
                CreatedDate = data.CreatedDate,
                ExcelUploadHistoryId = data.ExcelUploadHistoryId,
                ProductStatus = data.ProductStatus,
                SheetName = data.SheetName,
                SheetType = data.SheetType,
                TypeOf = data.TypeOf,
                UploadedBy = data.UploadedBy
            };
        }
    }
}