namespace Hims.Api.Controllers
{
    using Domain.Services;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Shared.DataFilters;
    using Shared.UserModels.ChargeModule;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Utilities;

    [Authorize]
    [Route("api/charge-module")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class ChargeModuleController : BaseController
    {
        private readonly IChargeModuleService chargeModuleServices;

        public ChargeModuleController(IChargeModuleService chargeModuleServices)
        {
            this.chargeModuleServices = chargeModuleServices;
        }

        #region Charge Templates

        [HttpPost]
        [Route("fetch-charge-templates")]
        public async Task<ActionResult> FetchChargeTemplatesAsync([FromBody] ChargeTemplateFilterModel model)
        {
            var response = await this.chargeModuleServices.FetchChargeTemplatesAsync(model);
            return this.Success(response);
        }

        [HttpPost]
        [Route("modify-charge-template")]
        public async Task<ActionResult> ModifyChargeTemplateAsync([FromBody] ChargeModuleTemplateModel model)
        {
            model = (ChargeModuleTemplateModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.ModifyChargeTemplateAsync(model);
            var message = string.Empty;
            switch (response)
            {
                case -1:
                    message = "The template name already exists.";
                    break;
                case -2:
                    message = "The template you trying to edit does not exists.";
                    break;
            }

            return !string.IsNullOrEmpty(message) ? this.BadRequest(message) : this.Success();
        }

        [HttpPost]
        [Route("set-in-use-template")]
        public async Task<ActionResult> SetInUseChargeTemplateAsync([FromBody] ChargeModuleTemplateModel model)
        {
            model = (ChargeModuleTemplateModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.SetInUseChargeTemplateAsync(model);
            return response ? this.Success() : this.ServerError();
        }

        #endregion

        /// <summary>
        /// Modify the charge asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-charge")]
        public async Task<ActionResult> ModifyChargeAsync([FromBody] ChargeModuleInsertionModel model)
        {
            model = (ChargeModuleInsertionModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.ModifyChargeAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the charge asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-given-charge")]
        public async Task<ActionResult> FetchChargeAsync([FromBody] ChargeModuleDetailsModel model)
        {
            model = (ChargeModuleDetailsModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.FetchGivenChargesAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Deletes the charge asynchronous.
        /// </summary>
        /// <param name="chargeModuleDetailsId">The charge module details identifier.</param>
        /// <returns></returns>
        [HttpGet]
        [Route("delete-charge")]
        public async Task<ActionResult> DeleteChargeAsync(int chargeModuleDetailsId)
        {
            if (chargeModuleDetailsId == 0)
            {
                return this.BadRequest("Invalid identifier supplied.");
            }

            var response = await this.chargeModuleServices.DeleteChargeAsync(chargeModuleDetailsId);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the doctor specialization charge asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-doctor-specialization-given-charge")]
        public async Task<ActionResult> FetchDoctorSpecializationChargeAsync([FromBody] DoctorSpecializationChargeModuleDetailsModel model)
        {
            model = (DoctorSpecializationChargeModuleDetailsModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.FetchDoctorSpecializationGivenChargesAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the specialization doctor consultation type charge asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-doctor-specialization-charge")]
        public async Task<ActionResult> ModifySpecializationDoctorConsultationTypeChargeAsync([FromBody] DoctorSpecializationChargeModuleInsertionModel model)
        {
            model = (DoctorSpecializationChargeModuleInsertionModel)EmptyFilter.Handler(model);
            var response = await this.chargeModuleServices.ModifyDoctorSpecializationChargeAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Deletes the doctor specialization charge asynchronous.
        /// </summary>
        /// <param name="doctorSpecializationChargeModuleDetailsId">The doctor specialization charge module details identifier.</param>
        /// <returns></returns>
        [HttpGet]
        [Route("delete-doctor-specialization-charge")]
        public async Task<ActionResult> DeleteDoctorSpecializationChargeAsync(int doctorSpecializationChargeModuleDetailsId)
        {
            if (doctorSpecializationChargeModuleDetailsId == 0)
            {
                return this.BadRequest("Invalid identifier supplied.");
            }

            var response = await this.chargeModuleServices.DeleteDoctorSpecializationChargeAsync(doctorSpecializationChargeModuleDetailsId);
            return this.Success(response);
        }


        [HttpPost]
        [Route("fetch-or-create-referenceid")]
        public async Task<ActionResult> FetchOrCreateRefernceId([FromBody] DoctorSpecializationChargeModuleDetailsModel model)
        {
            if (model.SpecializationId == 0 || model.ConsultationTypeId == 0)
            {
                return this.BadRequest("Invalid identifier supplied.");
            }

            var response = await this.chargeModuleServices.FetchOrCreateRefrenceId(model);
            if (response == null)
            {
                return this.BadRequest("Error in Fetching Reference Id");
            }
            model.ReferenceId = (int?)response.DoctorSpecializationMapId;
            model.FollowUpDaysLimit = response.FollowUpDaysLimit;
            model.FollowUpDays = response.FollowUpDays;
            var abc = new DoctorSpecializationChargeModuleDetailsModel()
            {
                ChargeModuleTemplateId = model.ChargeModuleTemplateId,
                ReferenceId = model.ReferenceId,
                ModulesMasterId = model.ModulesMasterId
            };
            model.Charges = (List<DoctorSpecializationChargeModuleDetailsModel>)await this.chargeModuleServices.FetchDoctorSpecializationGivenChargesAsync(abc);
            return this.Success(model);
        }

        #region Update Location Charges

        [HttpPost]
        [Route("fetch-location-charge-prices")]
        public async Task<ActionResult> FetchLocationChargePricesAsync([FromBody] LocationChargePriceRequestModel model)
        {
            model = (LocationChargePriceRequestModel)EmptyFilter.Handler(model);
            var result = await this.chargeModuleServices.FetchLocationChargePricesAsync(model.LocationId, model.ChargeModuleTemplateId, model.ModulesMasterId, model.ChargeReferenceId);
            return this.Success(result);
        }

        [HttpPost]
        [Route("update-location-charge-prices")]
        public async Task<ActionResult> UpdateLocationChargePricesAsync([FromBody] List<ChargeModuleDetailsModel> model)
        {
            model = (List<ChargeModuleDetailsModel>)EmptyFilter.Handler(model);
            var result = await this.chargeModuleServices.UpdateLocationChargePricesAsync(model);
            return result ? this.Success() : this.ServerError();
        }

        #endregion
    }

    public class LocationChargePriceRequestModel
    {
        public int LocationId { get; set; }

        public int ChargeModuleTemplateId { get; set; }

        public int ModulesMasterId { get; set; }

        public int ChargeReferenceId { get; set; }
    }
}