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

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

        /// <summary>
        /// Initializes a new instance of the <see cref="AuditLogServices"/> class.
        /// </summary>
        /// <param name="unitOfWork">
        /// The unit of work.
        /// </param>
        public AuditLogServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public Task<IEnumerable<AuditLogModel>> FetchAsync(AuditLogFilterModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (model.LogTypeId != null)
            {
                where += $@" AND log.""LogTypeId"" = '{model.LogTypeId}'";
            }
            if (model.RoleId != null)
            {
                where += $@" AND rl.""RoleId"" = '{model.RoleId}'";
            }

            if (model.AccountId != null)
            {
                where += $@" AND log.""AccountId"" = '{model.AccountId}'";
            }

            if (!string.IsNullOrEmpty(model.Description))
            {
                where += $@" AND log.""LogDescription"" ILIKE '%{model.Description}%'";
            }

            if (!string.IsNullOrEmpty(model.FromDate) && !string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" AND (""LogDate"" at time zone 'UTC' at time zone 'Asia/Kolkata')::DATE >= '{model.FromDate}'::DATE";
                where += $@" AND (""LogDate"" at time zone 'UTC' at time zone 'Asia/Kolkata')::DATE <= '{model.ToDate}'::DATE";
            }

            if (!string.IsNullOrEmpty(model.RoleName))
            {
                where += $@" AND rl.""RoleName"" ILIKE '%{model.RoleName}%'";
            }
            if (!string.IsNullOrEmpty(model.FullName))
            {
                where += $@" AND acc.""FullName"" ILIKE '%{model.FullName}%'";
            }
            if (!string.IsNullOrEmpty(model.LogTypeName))
            {
                where += $@" AND lkp.""LogTypeName"" ILIKE '%{model.LogTypeName}%'";
            }
            if (model.LocationId!=null)
            {
                where += $@" AND log.""LocationId"" = '{model.LocationId}'";
            }

            var query = $@"SELECT COUNT(*) OVER() AS ""TotalItems"", log.*, acc.""FullName"", rl.""RoleName"",rl.""RoleId"", lkp.""LogTypeName"" FROM ""AuditLog"" log
                        LEFT JOIN ""Account"" acc ON acc.""AccountId"" = log.""AccountId"" AND acc.""Active"" IS TRUE
                        LEFT JOIN ""Role"" rl ON rl.""RoleId"" = acc.""RoleId"" AND rl.""Active"" IS TRUE
                        LEFT JOIN ""LogType"" lkp ON lkp.""LogTypeId"" = log.""LogTypeId"" AND lkp.""Active"" IS TRUE
                        {where} Order by log.""AuditLogId"" DESC";

            if (model.PageIndex <= 0)
            {
                return this.unitOfWork.Current.QueryAsync<AuditLogModel>(query);
            }

            model.PageIndex -= 1;
            query += " LIMIT " + model.PageSize + " offset " + (model.PageIndex * model.PageSize);
            return this.unitOfWork.Current.QueryAsync<AuditLogModel>(query);
        }

        /// <inheritdoc />
        public Task LogAsync(AuditLogModel model)
        {
             

            var auditLog = new AuditLog
            {
                LogDate = DateTime.UtcNow,
                AccountId = model.AccountId,
                LogFrom = model.LogFrom,
                LogTypeId = model.LogTypeId,
                LogDescription = model.LogDescription,
                LocationId=model.LocationId,
                
            };

            return this.unitOfWork.AuditLogs.InsertAsync(auditLog);
        }
    }
}