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

namespace Hims.Infrastructure.Services
{
    public class AmbulanceRecieptService : IAmbulanceRecieptService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <inheritdoc cref="IAmbulanceRecieptService" />
        public AmbulanceRecieptService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;


        private async Task<string> GetLatestRecieptNumber()
        {
            var previous = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>($@"select ""RecieptNo"" from ""AmbulanceReciept"" order by ""AmbulanceRecieptId"" desc limit 1");
            if (previous == null)
            {
                return $@"{DateTime.Now.ToString("yyyy")}1";
            }
            else
            {
                var year = previous[..4];
                var getCurrentYear = DateTime.Now.ToString("yyyy");
                if (year != getCurrentYear)
                {
                    return $@"{getCurrentYear}1";
                }
                var sequenceNumber = previous.Replace(year, "");
                return $@"{year}{Convert.ToInt64(sequenceNumber) + 1}";
            }
        }





        public async Task<int> InsertAsync(AmbulanceRecieptModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""AmbulanceReciept"" where  (""RecieptNo"") = '{model.RecieptNo}'");
            if (checkIf > 0)
            {
                return -1;
            }
            var ambulanceReciept = new AmbulanceReciept
            {
                AmbulanceRecieptId = model.AmbulanceRecieptId,
                RecieptNo = await this.GetLatestRecieptNumber(),
                FromLocation = model.FromLocation,
                Address = model.Address,
                ToLocation = model.ToLocation,
                PatientName = model.PatientName,
                PatientMobile = model.PatientMobile,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                DriverDetailId = model.DriverDetailId,
                AmbulanceId = model.AmbulanceId,
                Amount = model.Amount,
                LocationId = model.LocationId
            };
            return await this.unitOfWork.AmbulanceReciept.InsertAsync(ambulanceReciept);


        }
        public async Task<IEnumerable<AmbulanceRecieptModel>> FetchAllAsync(AmbulanceRecieptModel model)
        {
            var where = "where 1=1";
            if (model.LocationId > 0)
            {
                where += $@" and  ar.""LocationId"" = {model.LocationId} ";
            }
            var query = $@"select count(ar.""AmbulanceRecieptId"") over() as ""TotalItems"",ar.*,a.""AmbulanceNo"",d.""DriverDetailName"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""AmbulanceReciept""  ar
                             join ""Ambulance"" a on a.""AmbulanceId""=ar.""AmbulanceId""
                             join ""DriverDetail"" d on  d.""DriverDetailId""=ar.""DriverDetailId""
                             join ""Account"" C on C.""AccountId"" = ar.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = ar.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where}
                             order by ar.""CreatedDate"" desc";

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

        }

        public async Task<int> UpdateAsync(AmbulanceRecieptModel model)
        {
            
                var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""AmbulanceReciept"" WHERE (""RecieptNo"") = '{model.RecieptNo}' and ""AmbulanceRecieptId""<>{model.AmbulanceRecieptId} ");
                if (checkIf > 0)
                {
                    return -1;
                }

                var ambulanceReciept = await this.unitOfWork.AmbulanceReciept.FindAsync(m => m.AmbulanceRecieptId == model.AmbulanceRecieptId);

                ambulanceReciept.AmbulanceRecieptId = model.AmbulanceRecieptId;
                ambulanceReciept.RecieptNo = model.RecieptNo;
                ambulanceReciept.FromLocation = model.FromLocation;
                ambulanceReciept.Address = model.Address;
                ambulanceReciept.ToLocation = model.ToLocation;
                ambulanceReciept.PatientName = model.PatientName;
                ambulanceReciept.PatientMobile = model.PatientMobile;
                ambulanceReciept.ModifiedBy = model.CreatedBy;
                ambulanceReciept.ModifiedDate = DateTime.Now;
                ambulanceReciept.DriverDetailId = model.DriverDetailId;
                ambulanceReciept.AmbulanceId = model.AmbulanceId;
                ambulanceReciept.Amount = model.Amount;                
                return await this.unitOfWork.AmbulanceReciept.UpdateAsync(ambulanceReciept);

            
        }

    }

}
