namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Hims.Shared.UserModels;
    using Hims.Shared.UserModels.TemplateDesign.Component;

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

        /// <inheritdoc cref="IComponentService" />
        public ComponentService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        public Task<int> DeleteAsync(DeleteModel model)
        {
            throw new NotImplementedException();
        }

        public async Task<IEnumerable<FetchModel>> FetchAllAsync(FetchModel model)
        {
            var where = $@"";
            var query = $@"Select count(ct.""ComponentId"") over() as ""TotalItems"",ct.""CreatedDate"",ct.""Active"",ct.""ComponentId"",ct.""Name"",ct.""ComponentTypeId"",ct.""CreatedBy"",cc.""FullName"" as ""CreatedByName""
,ac.""FullName"" as ""ModifiedByName"",ct.""ModifiedBy"",ct.""ModifiedDate"" from ""template"".""Component"" ct
left join ""Account"" cc on cc.""AccountId""= ct.""CreatedBy""
left join ""Account"" ac on ac.""AccountId"" = ct.""ModifiedBy""";
            return await this.unitOfWork.Current.QueryAsync<FetchModel>(query);
        }

        public async Task<int> InsertAsync(InsertModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"SELECT Count(*) from ""template"".""Component"" where lower(""Name"")='{model.Name}'");

            if (checkIf > 0)
            {
                return -1;
            }
            var component = new Component
            {
                Name = model.Name,
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                ComponentTypeId = model.ComponentTypeId
            };
            return await this.unitOfWork.Components.InsertAsync(component);
        }

        public async Task<int> UpdateAsync(UpdateModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"Select count(*) from ""template"".""Component"" where lower(""Name"")='{model.Name}' and ""ComponentId"" <> {model.ComponentId}");

            if (checkIf > 0)
            {
                return -1;
            }
            var record = await this.unitOfWork.Components.FindAsync(x => x.ComponentId == model.ComponentId);
            if (record != null)
            {
                record.ModifiedDate = DateTime.Now;
                record.ModifiedBy = model.CreatedBy;
                record.Name = model.Name;
                record.ComponentTypeId = model.ComponentTypeId;

            }
            return await this.unitOfWork.Components.UpdateAsync(record);
        }
    }
}