using System;
using Hims.Shared.UserModels.Common;
using Hims.Shared.UserModels.MasterBill;

namespace Hims.Api.Controllers
{
    using System.Threading.Tasks;

    using Domain.Services;
    using Hims.Api.Models;
    using Hims.Domain.Configurations;
    using Hims.Domain.Entities;
    using Hims.Domain.Helpers;
    using Hims.Infrastructure.Helpers;
    using Hims.Shared.EntityModels;
    using Hims.Shared.Library.Enums;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Utilities;

    /// <inheritdoc />
    [Authorize]
    [Route("api/masterbill")]
    public class MasterBillController : BaseController
    {
        /// <summary>
        /// The service
        /// </summary>
        private readonly IMasterBillService service;

        /// <summary>
        /// The auditlog services.
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IPatientService patientServices;

        /// <summary>
        /// The AES helper.
        /// </summary>
        private readonly IAESHelper aesHelper;

        /// <summary>
        /// The application configuration.
        /// </summary>
        private readonly IApplicationConfiguration applicationConfiguration;

        /// <inheritdoc />
        public MasterBillController(IMasterBillService service, IAuditLogService auditLogServices, IPatientService patientServices, IAESHelper aesHelper, IApplicationConfiguration applicationConfiguration)
        {
            this.service = service;
            this.auditLogServices = auditLogServices;
            this.patientServices = patientServices;
            this.aesHelper = aesHelper;
            this.applicationConfiguration = applicationConfiguration;
        }


        /// <summary>
        /// Inserts the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        [Route("fetch")]
        public async Task<ActionResult> FetchAsync([FromBody] InsertModel model, [FromHeader] LocationHeader header)
        {
            model.LocationId = !string.IsNullOrEmpty(header.LocationId) ? int.Parse(header.LocationId) : (int?)null;
            try
            {
                var response = await this.service.FetchAsync(model);
                foreach (var item in response)
                {
                    if (!string.IsNullOrEmpty(item.PaymentInitiationLogId))
                    {
                        var tokens = item.PaymentInitiationLogId.Split("\"");
                        item.PaymentIntiateUrl = this.applicationConfiguration.SalucroPaymentLink + "?id=" + this.aesHelper.Encode(tokens[1]) + "&mode=" + "Payment";
                    }
                    item.PendingAmount = item.NetTotal - item.PaidAmount;
                }

                return Ok(new GenericResponse
                {
                    Status = response != null ? GenericStatus.Success : GenericStatus.Info,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }
        /// <summary>
        /// Inserts the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        [Route("fetch-patient-due")]
        public async Task<ActionResult> FetchPatientDueAsync([FromBody] FilterModel model, [FromHeader] LocationHeader header)
        {
            model.LocationId = !string.IsNullOrEmpty(header.LocationId) ? int.Parse(header.LocationId) : (int?)null;
            var response = await this.service.FetchPatientDueAsync(model);
            foreach (var item in response)
            {
                item.EncryptedPatientId = this.aesHelper.Encode(item.PatientId.ToString());
            }
            return this.Success(response);
        }
        /// <summary>
        /// Inserts the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        [Route("fetch-packages")]
        public async Task<ActionResult> FetchPackagesAsync([FromBody] InsertModel model, [FromHeader] LocationHeader header)
        {
            model.LocationId = !string.IsNullOrEmpty(header.LocationId) ? int.Parse(header.LocationId) : (int?)null;
            try
            {
                var response = await this.service.FetchPackagesAsync(model);
                return Ok(new GenericResponse
                {
                    Status = response != null ? GenericStatus.Success : GenericStatus.Info,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        ///// <summary>
        ///// Inserts the asynchronous.
        ///// </summary>
        ///// <param name="model">The model.</param>
        ///// <returns></returns>
        //[AllowAnonymous]
        //[HttpPost]
        //[Route("add")]
        //public async Task<ActionResult> InsertAsync([FromBody] InsertModel model, [FromHeader] LocationHeader header)
        //{
        //    try
        //    {

        //        model.CreatedDate = DateTime.Now;
        //        var response = await this.service.InsertAsync(model);
        //        var patientFullName = await this.patientServices.FindPatientByPatientId((int)model.PatientId);
        //        if (response > 0)
        //        {
        //            var auditLogModel = new AuditLogModel
        //            {
        //                AccountId = model.CreatedBy,
        //                LogTypeId = (int)LogTypes.Masters,
        //                LogFrom = (short)model.RoleId,
        //                LogDate = DateTime.UtcNow.AddMinutes(330),
        //                LogDescription = $"<b>{model.FullName}</b> has <b>Generated the Bill</b> for  the Patient <b>{patientFullName}</b> on <b>{DateTime.UtcNow.AddMinutes(330)}</b> .",
        //                LocationId = Convert.ToInt32(header.LocationId)
        //            };
        //            await this.auditLogServices.LogAsync(auditLogModel);
        //        }

        //        return Ok(new GenericResponse
        //        {
        //            Status = response > 0 ? GenericStatus.Success : GenericStatus.Error,
        //            Data = response
        //        });
        //    }
        //    catch (Exception ex)
        //    {
        //        return Ok(new GenericResponse
        //        {
        //            Status = GenericStatus.Error,
        //            Message = ex.Message
        //        });
        //    }
        //}

        ///// <summary>
        ///// Inserts the asynchronous.
        ///// </summary>
        ///// <param name="model">The model.</param>
        ///// <returns></returns>
        //[AllowAnonymous]
        //[HttpPost]
        //[Route("update")]
        //public async Task<ActionResult> UpdateAsync([FromBody] InsertModel model, [FromHeader] LocationHeader header)
        //{
        //    try
        //    {
        //        model.ModifiedDate = DateTime.Now;
        //        var response = await this.service.UpdateAsync(model).ConfigureAwait(false);
        //        var patientFullName = await this.patientServices.FindPatientByPatientId((int)model.PatientId);
        //        if (response > 0)
        //        {
        //            var auditLogModel = new AuditLogModel
        //            {
        //                AccountId = model.ModifiedBy,
        //                LogTypeId = (int)LogTypes.Masters,
        //                LogFrom = (short)model.RoleId,
        //                LogDate = DateTime.UtcNow.AddMinutes(330),
        //                LogDescription = $"<b>{model.FullName}</b> has <b>updated</b> the Bill for the Patient <b>{patientFullName}</b>  on <b>{DateTime.UtcNow.AddMinutes(330)}</b>",
        //                LocationId = Convert.ToInt32(header.LocationId)
        //            };
        //            await this.auditLogServices.LogAsync(auditLogModel);

        //        }
        //        return Ok(new GenericResponse
        //        {
        //            Status = response > 0 ? GenericStatus.Success : GenericStatus.Error,
        //            Data = response
        //        });
        //    }
        //    catch (Exception ex)
        //    {
        //        return Ok(new GenericResponse
        //        {
        //            Status = GenericStatus.Error,
        //            Message = ex.Message
        //        });
        //    }
        //}

        /// <summary>
        /// Inserts the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("fetch-for-excel")]
        public async Task<ActionResult> FetchForExcelAsync([FromBody] FilterModel model, [FromHeader] LocationHeader header)
        {
            model.LocationId = model.LocationId > 0 ? model.LocationId : !string.IsNullOrEmpty(header.LocationId) ? Convert.ToInt32(header.LocationId) : (int?)null;
            try
            {
                var response = await this.service.FetchExcelAsync(model);

                return Ok(new GenericResponse
                {
                    Status = response != null ? GenericStatus.Success : GenericStatus.Info,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }


    }
}