namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using AutoMapper;

    using Utilities;
    using Domain.Helpers;
    using Domain.Services;

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;
    using Shared.UserModels.Filters;
    using Hims.Shared.UserModels;
    using Hims.Shared.EntityModels;

    /// <summary>
    /// The practice controller.
    /// </summary>
    [Route("api/mobile")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class MobileController : BaseController
    {
        /// <summary>
        /// The Auto Mapper
        /// </summary>
        private readonly IMapper mapper;

        /// <summary>
        /// the practice services
        /// </summary>
        private readonly IProviderService providerServices;

        /// <summary>
        /// the practice services
        /// </summary>
        private readonly IResourceService resourceService;

        /// <summary>
        /// the practice services
        /// </summary>
        private readonly IAppointmentService appointmentsServices;

        /// <summary>
        /// the practice services
        /// </summary>
        private readonly IWebTelemedicineService webTelemedicineService;

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

        /// <summary>
        /// The patient document helper.
        /// </summary>
        private readonly IPatientDocumentService patientDocumentServices;

        /// <summary>
        /// The patient medication service
        /// </summary>
        private readonly IPatientEncounterService patientEncounterService;

        /// <inheritdoc />
        public MobileController(IProviderService providerServices, IAESHelper aesHelper, IMapper mapper, IResourceService resourceService, IAppointmentService appointmentsServices, IWebTelemedicineService webTelemedicineService, IPatientDocumentService patientDocumentServices, IPatientEncounterService patientEncounterService)
        {
            this.providerServices = providerServices;
            this.aesHelper = aesHelper;
            this.mapper = mapper;
            this.resourceService = resourceService;
            this.appointmentsServices = appointmentsServices;
            this.webTelemedicineService = webTelemedicineService;
            this.patientDocumentServices = patientDocumentServices;
            this.patientEncounterService = patientEncounterService;
        }

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="patientId">
        /// The patient id.
        /// </param>
        /// <param name="accountId">
        /// The account id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch")]
        [ProducesResponseType(typeof(IEnumerable<ProviderListItemModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchAsync(int patientId, int accountId)
        {
            var model = new ProviderListItemFilterModel
            {
                PatientId = patientId
            };

            var appointmentsFilterModel = new AppointmentFilterModel
            {
                PatientId = patientId,
                AccountId = accountId,
                PageIndex = 1,
                PageSize = 10,
                isMobile = true
            };

            var providers = await this.providerServices.FetchListItemsAsync(model);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());

                var date = DateTime.Now;
                var day = ((int)(date.DayOfWeek + 6) % 7) + 1;

                if (!string.IsNullOrEmpty(provider.Availability))
                {
                    var slots = JsonConvert.DeserializeObject<List<ProviderShiftModel>>(provider.Availability);
                    var availability = slots.FirstOrDefault(m => m.Day == day) ?? new ProviderShiftModel();
                    provider.ChargeType = availability.ChargeType;
                }
            }

            //var symptoms = await this.resourceService.ServicesAsync();
            var specializations = await this.resourceService.SpecializationsAsync();

            var appointments = await this.appointmentsServices.FetchAllAsync(appointmentsFilterModel);

            var appointmentModels = appointments.ToList();
            if (!string.IsNullOrEmpty(appointmentsFilterModel.EncryptedPatientId) && appointmentModels.ToArray().Length == 0)
            {
                appointments = new List<AppointmentModel> { new AppointmentModel { PatientId = Convert.ToInt32(model.PatientId) } };
                return this.Success(appointments);
            }

            var domain = await this.webTelemedicineService.GetActiveDomain(null);
            foreach (var item in appointmentModels)
            {
                var roomName = item.AppointmentNo + "-" + item.PatientName?.Trim().Replace(' ', '-').Replace("--", "-");
                item.RoomName = roomName;
                item.Domain = domain.Domain;
                var documentModel = new PatientDocumentFilterModel();
                documentModel.PatientId = item.PatientId;
                documentModel.PageIndex = 1;
                documentModel.PageSize = 1;

                try
                {
                    var getPatientMedication = (await this.patientEncounterService.FetchPatientMedication(new Shared.UserModels.PatientMedication.PatientMedicationHeaderModel { AppointmentId = item.AppointmentId })).ToList();
                    if (getPatientMedication.Count > 0)
                    {
                        item.IsPrescription = true;
                    }
                    else
                    {
                        item.IsPrescription = false;
                    }
                }
                catch (Exception)
                {
                    // ignore
                }

                var patientDocuments = await this.patientDocumentServices.FetchAsync(documentModel);

                item.PatientDocumentCount = patientDocuments == null || patientDocuments.ToList().Count() == 0 ? 0 : patientDocuments.ToList()[0].TotalItems;

                if (item.CallType != null)
                {
                    item.CallTypeName = item.CallType == 1 ? "Video" : "Audio";
                }

                if (item.CallStatus != null)
                {
                    item.CallStatusName = item.CallStatus == 1
                                                ? item.ReceiverCallStatus == 2
                                                    ? "Call Complete"
                                                    : item.ReceiverCallStatus == 3
                                                        ? "Rejected Call" : "Missed Call"
                                            : item.CallStatus == 2 ? "Join"
                                            : item.CallStatus == 3 ? "Call Complete"
                                            : item.CallStatus == 4 ? "Cancelled" : string.Empty;
                }

                // SUPPORT CALL CONCEPT
                var prefix = "VS Support ";
                if (item.CallerRoleId == 5 || item.CallerRoleId == 2)
                {
                    if (item.CallStatus != null)
                    {
                        item.CallStatusName = item.CallStatus == 1
                                                    ? item.ReceiverCallStatus == 2
                                                        ? prefix + "Call Complete"
                                                        : item.ReceiverCallStatus == 3
                                                            ? prefix + "Rejected Call" : prefix + "Missed Call"
                                                : item.CallStatus == 2 ? prefix + "Join"
                                                : item.CallStatus == 3 ? prefix + "Call Complete"
                                                : item.CallStatus == 4 ? prefix + "Cancelled" : string.Empty;
                    }
                }

                // New Implementation 13th May 2021
                // var date = item.CallStatusModifiedDate ?? item.CallStatusDate;
                if (item.InProgress == true)
                {
                    item.CallStatus = 2;
                    item.CallStatusName = "Join";
                }

                // SUPPORT CALL CONCEPT
                if (item.CallerRoleId == 5 || item.CallerRoleId == 2)
                {
                    if (item.InProgress == true)
                    {
                        item.CallStatus = 2;
                        item.CallStatusName = prefix + "Join";
                    }
                }

                // This case happen when Doctor or Nurse call to Doctor or nurse
                // with no patient in the call and call has been ended
                if (item.InProgress == false && item.CallStatus == 2)
                {
                    item.CallStatus = 1;
                    // SUPPORT CALL CONCEPT
                    if (item.CallerRoleId == 5 || item.CallerRoleId == 2)
                    {
                        item.CallStatusName = prefix + "Missed Call";
                    }
                    else
                    {
                        item.CallStatusName = "Missed Call";
                    }
                }

                item.EncryptedAppointmentId = this.aesHelper.Encode(item.AppointmentId.ToString());
                item.EncryptedPatientId = this.aesHelper.Encode(item.PatientId.ToString());
                item.EncryptedProviderId = this.aesHelper.Encode(item.ProviderId.ToString());
                if (item.IsUTC == true)
                {
                    var timeZones = TimeZoneInfo.GetSystemTimeZones();
                    var appintmentDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")).Add(item.AppointmentTime);
                    var timeZone1 = timeZones.FirstOrDefault(m => m.Id == "India Standard Time");
                    var currentDateTime1 = TimeZoneInfo.ConvertTimeFromUtc(appintmentDate, timeZone1);
                    var currentTime1 = currentDateTime1.ToString("HH:mm");
                    item.AppointmentTime = TimeSpan.Parse(currentTime1);

                    var currentDateTime = TimeZoneInfo.ConvertTimeFromUtc(Convert.ToDateTime(item.AppointmentDateTime), timeZone1);
                    var currentTime = currentDateTime.ToString("MM/dd/yyyy hh:mm tt");
                    item.AppointmentDateTime = currentTime;
                }
                item.AppointmentTimeString = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")).Add(item.AppointmentTime).ToString("hh:mm tt");
            }

            return this.Success(new { Providers = providers, Specializations = specializations, Appointments = appointments });
        }
    }
}