// Ignore Spelling: aes

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Hims.Api.Utilities;
using Hims.Domain.Services;
using Hims.Shared.EntityModels;
using System;
using Hims.Domain.Helpers;
using Hims.Domain.Configurations;
using Hims.Shared.Library.Enums;
using System.Linq;
using System.Collections.Generic;
using Hims.Domain.Entities;
using Hims.Shared.UserModels.Common;
using Hims.Shared.UserModels.Counselling;
using Hims.Api.Models;

namespace Hims.Api.Controllers
{
    [Route("api/counselling")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class CounsellingController : BaseController
    {
        private readonly IAESHelper aesHelper;
        private readonly IFtpUploadHelper ftpUploadHelper;
        private readonly IAccountService accountServices;
        private readonly ICounsellingService counsellingServices;
        private readonly IRunningEnvironment runningEnvironment;

        public CounsellingController(ICounsellingService counsellingServices, IAESHelper aesHelper, IFtpUploadHelper ftpUploadHelper, IRunningEnvironment runningEnvironment, IAccountService accountServices)
        {
            this.counsellingServices = counsellingServices;
            this.aesHelper = aesHelper;
            this.runningEnvironment = runningEnvironment;
            this.ftpUploadHelper = ftpUploadHelper;
            this.accountServices = accountServices;
        }

        [HttpGet]
        [Route("fetch")]
        public async Task<ActionResult> FetchAsync(string patientId)
        {
            var counsellings = await this.counsellingServices.FetchAsync(Convert.ToInt32(this.aesHelper.Decode(patientId)));
            if (counsellings.Any())
            {
                foreach (var counselling in counsellings)
                {
                    if (!string.IsNullOrEmpty(counselling.PatientSignature))
                    {
                        var guid = await this.accountServices.FindGuidAsync(counselling.PatientId, Roles.Patient);
                        counselling.PatientSignatureRootPath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/";
                    }

                    if (!string.IsNullOrEmpty(counselling.CounsellorSignature))
                    {
                        var guid = await this.accountServices.FindGuidAsync(counselling.CreatedBy, (Roles)counselling.CreatedByRoleId);
                        counselling.CounsellorSignatureRootPath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/";
                    }
                }
            }

            return this.Success(counsellings);
        }

        [HttpPost]
        [Route("fetch-basics")]
        public async Task<ActionResult> FetchBasicsAsync([FromBody] PackageTypeModel model, [FromHeader] LocationHeader header)
        {
            model.LocationId = Convert.ToInt32(header.LocationId);
            var data = await this.counsellingServices.FetchBasicsAsync(model);
            return this.Success(new GenericResponse
            {
                Status = GenericStatus.Success,
                Data = data
            });
        }

        [HttpGet]
        [Route("find")]
        public async Task<ActionResult> FindAsync(int counsellingId)
        {
            var counselling = await this.counsellingServices.FindAsync(counsellingId);
            if (counselling != null && counselling.CounsellingId != 0)
            {
                if (!string.IsNullOrEmpty(counselling.PatientSignature))
                {
                    var guid = await this.accountServices.FindGuidAsync(counselling.PatientId, Roles.Patient);
                    counselling.PatientSignatureRootPath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/";
                }

                if (!string.IsNullOrEmpty(counselling.CounsellorSignature))
                {
                    var guid = await this.accountServices.FindGuidAsync(counselling.CreatedBy, (Roles)counselling.CreatedByRoleId);
                    counselling.CounsellorSignatureRootPath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/";
                }

                var counsellingDetails = await this.counsellingServices.FetchDetailsAsync(counsellingId) ?? new List<CounsellingDetailModel>();
                return this.Success(new { counselling, counsellingDetails });
            }

            return this.Failed("No counselling details found.");
        }

        [HttpGet]
        [Route("patient-info")]
        public async Task<ActionResult> FindPatientInfoAsync(int patientId)
        {
            var result = await this.counsellingServices.FindPatientInfoAsync(patientId);
            return this.Success(result);
        }

        [HttpPost]
        [Route("modify")]
        public async Task<ActionResult> ModifyAsync([FromBody] ModifyCounsellingRequest request)
        {
            int result;
            string message;
            if (request.Counselling.CounsellingId == 0)
            {
                result = await this.counsellingServices.AddAsync(request.Counselling, request.CounsellingDetails);
                message = "Counselling has been " + (request.Counselling.IsDraft ? "drafted" : "published") + " successfully.";
            }
            else
            {
                result = await this.counsellingServices.UpdateAsync(request.Counselling, request.CounsellingDetails);
                message = "Counselling has been updated successfully.";
            }

            if (result == 0)
                return ServerError();

            else if (result == -1)
                return Failed("There is already an active counselling program in place, so counselling cannot be added.");
            else
            {
                if (request.Counselling.CounsellingId == 0)
                    request.Counselling.CounsellingId = result;
            }

            // Patient Signature
            if (!string.IsNullOrEmpty(request.Counselling.PatientBase64Signature))
            {
                var guid = await this.accountServices.FindGuidAsync(request.Counselling.PatientId, Roles.Patient);
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/Signature";
                await this.ftpUploadHelper.CreateDirectory(filePath);

                var dbPath = $@"{request.Counselling.UMRNo}_Counselling_Signature_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(request.Counselling.PatientBase64Signature, filePath);
                    if (uploadResponse > 0)
                        request.Counselling.PatientSignature = $@"Signature/{dbPath}";
                }
                catch (Exception)
                {
                    request.Counselling.PatientSignature = null;
                }

                if (!string.IsNullOrEmpty(request.Counselling.PatientSignature))
                    await this.counsellingServices.UpdateSignaturesAsync(request.Counselling.CounsellingId, request.Counselling.PatientSignature, true);
            }

            // Counsellor Signature
            if (!string.IsNullOrEmpty(request.Counselling.CounsellorBase64Signature))
            {
                var guid = await this.accountServices.FindGuidAsync(request.Counselling.CreatedBy, (Roles)request.Counselling.CreatedByRoleId);
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/Signature";
                await this.ftpUploadHelper.CreateDirectory(filePath);

                var dbPath = $@"{request.Counselling.CreatedByName}_Counselling_Signature_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(request.Counselling.CounsellorBase64Signature, filePath);
                    if (uploadResponse > 0)
                        request.Counselling.CounsellorSignature = $@"Signature/{dbPath}";
                }
                catch (Exception)
                {
                    request.Counselling.CounsellorSignature = null;
                }

                if (!string.IsNullOrEmpty(request.Counselling.CounsellorSignature))
                    await this.counsellingServices.UpdateSignaturesAsync(request.Counselling.CounsellingId, request.Counselling.CounsellorSignature, false);
            }

            return Success(message);
        }

        [HttpPost]
        [Route("delete")]
        public async Task<ActionResult> DeleteAsync([FromBody] CounsellingModel model)
        {
            var result = await this.counsellingServices.DeleteAsync(model.CounsellingId);
            return result switch
            {
                0 => ServerError(),
                -1 => Failed("This counselling is already being used, so the selected counselling cannot be deleted."),
                _ => Success("Counselling has been deleted successfully."),
            };
        }

        [HttpPost]
        [Route("disable")]
        public async Task<ActionResult> DisableAsync([FromBody] CounsellingModel model)
        {
            var result = await this.counsellingServices.DisableAsync(model.CounsellingId, model.CreatedBy);
            return result <= 0 ? this.ServerError() : this.Success("Counselling has been disabled successfully.");
        }

        [HttpPost]
        [Route("enable")]
        public async Task<ActionResult> EnableAsync([FromBody] CounsellingModel model)
        {
            var result = await this.counsellingServices.EnableAsync(model.CounsellingId, model.CreatedBy);
            return result switch
            {
                0 => ServerError(),
                -1 => Failed("There is already an enable counselling program in place, so the selected counselling cannot be enabled."),
                _ => Success("Counselling has been enabled successfully."),
            };
        }

        [HttpPost]
        [Route("publish")]
        public async Task<ActionResult> PublishAsync([FromBody] CounsellingModel model)
        {
            var result = await this.counsellingServices.PublishAsync(model.CounsellingId, model.CreatedBy);
            if (result <= 0)
                return this.ServerError();

            // Patient Signature
            if (!string.IsNullOrEmpty(model.PatientBase64Signature))
            {
                var guid = await this.accountServices.FindGuidAsync(model.PatientId, Roles.Patient);
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/Signature";
                await this.ftpUploadHelper.CreateDirectory(filePath);

                var dbPath = $@"{model.UMRNo}_Counselling_Signature_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.PatientBase64Signature, filePath);
                    if (uploadResponse > 0)
                        model.PatientSignature = $@"Signature/{dbPath}";
                }
                catch (Exception)
                {
                    model.PatientSignature = null;
                }

                if (!string.IsNullOrEmpty(model.PatientSignature))
                    await this.counsellingServices.UpdateSignaturesAsync(model.CounsellingId, model.PatientSignature, true);
            }

            // Counsellor Signature
            if (!string.IsNullOrEmpty(model.CounsellorBase64Signature))
            {
                var guid = await this.accountServices.FindGuidAsync(model.CreatedBy, (Roles)model.CreatedByRoleId);
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/Signature";
                await this.ftpUploadHelper.CreateDirectory(filePath);

                var dbPath = $@"{model.CreatedByName}_Counselling_Signature_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.CounsellorBase64Signature, filePath);
                    if (uploadResponse > 0)
                        model.CounsellorSignature = $@"Signature/{dbPath}";
                }
                catch (Exception)
                {
                    model.CounsellorSignature = null;
                }

                if (!string.IsNullOrEmpty(model.CounsellorSignature))
                    await this.counsellingServices.UpdateSignaturesAsync(model.CounsellingId, model.CounsellorSignature, false);
            }

            return this.Success();
        }

        public class ModifyCounsellingRequest
        {
            public CounsellingModel Counselling { get; set; }

            public List<CounsellingDetailModel> CounsellingDetails { get; set; }
        }
    }
}