namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Domain.Services;
    using Hims.Api.Models;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.CodeAnalysis.CSharp;
    using Npgsql;
    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.Library.Enums;
    using Shared.UserModels;
    using Utilities;

    /// <inheritdoc />
    [Authorize]
    [Route("api/hwc-patient")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class HwcPatientController : BaseController
    {
        /// <summary>
        /// The coupon services.
        /// </summary>
        private readonly IHwcPatientService hocPatientService;

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

        /// <inheritdoc />
        public HwcPatientController(IHwcPatientService hocPatientService, IAuditLogService auditLogServices)
        {
            this.hocPatientService = hocPatientService;
            this.auditLogServices = auditLogServices;
        }

        /// <summary>
        /// Inserts the hoc asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("insert")]
        public async Task<ActionResult> InsertHocAsync([FromBody] HwcPatientModel model, [FromHeader] LocationHeader location)
        {
            model = (HwcPatientModel)EmptyFilter.Handler(model);
            model.LocationId = !string.IsNullOrEmpty(location.LocationId) ? int.Parse(location.LocationId) : (int?)null;
            var response = await this.hocPatientService.InsertAsync(model);
            try
            {
                if (response > 0)
                {
                    var auditLogModel = new AuditLogModel
                    {
                        AccountId = model.CreatedBy,
                        LogTypeId = (int)LogTypes.HWCPatients,
                        LogFrom = short.Parse(model.LoginRoleId.ToString()),
                        LogDate = DateTime.UtcNow,
                        LocationId = (int)model.LocationId,
                        LogDescription = $" {model.CreatedByName} has added new <b>HWC</b> type : <strong>{model.HWCName}</strong>."
                    };
                    await this.auditLogServices.LogAsync(auditLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// Inserts the hoc asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("update")]
        public async Task<ActionResult> UpdateHocAsync([FromBody] HwcPatientModel model, [FromHeader] LocationHeader location)
        {
            model = (HwcPatientModel)EmptyFilter.Handler(model);
            model.LocationId = !string.IsNullOrEmpty(location.LocationId) ? int.Parse(location.LocationId) : (int?)null;
            var response = await this.hocPatientService.UpdateAsync(model);
            try
            {
                if (response > 0)
                {
                    var auditLogModel = new AuditLogModel
                    {
                        AccountId = model.CreatedBy,
                        LogTypeId = (int)LogTypes.HWCPatients,
                        LogFrom = short.Parse(model.LoginRoleId.ToString()),
                        LogDate = DateTime.UtcNow,
                        LocationId = (int)model.LocationId,
                        LogDescription = $" {model.CreatedByName} has updated the <b>HWC</b> type to : <strong>{model.HWCName}</strong>."
                    };
                    await this.auditLogServices.LogAsync(auditLogModel);
                }
            }
            catch (Exception)
            {
                // ignore
            }
            return this.Success(response);
        }

        /// <summary>
        /// Fetches all asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-all")]
        public async Task<ActionResult> FetchAllAsync([FromBody] HwcPatientModel model, [FromHeader] LocationHeader location)
        {
            model ??= new HwcPatientModel();
            model.LocationId = !string.IsNullOrEmpty(location.LocationId) ? int.Parse(location.LocationId) : (int?)null;
            var response = await this.hocPatientService.FetchAllAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Deletes the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("delete")]
        public async Task<ActionResult> DeleteAsync([FromBody] HwcPatientModel model, [FromHeader] LocationHeader location)
        {
            try
            {
                model = (HwcPatientModel)EmptyFilter.Handler(model);
                var response = await this.hocPatientService.DeleteAsync(model);
                try
                {
                    if (response > 0)
                    {
                        model.LocationId = !string.IsNullOrEmpty(location.LocationId) ? int.Parse(location.LocationId) : (int?)null;
                        var auditLogModel = new AuditLogModel
                        {
                            AccountId = model.CreatedBy,
                            LogTypeId = (int)LogTypes.HWCPatients,
                            LogFrom = short.Parse(model.LoginRoleId.ToString()),
                            LogDate = DateTime.UtcNow,
                            LocationId = (int)model.LocationId,
                            LogDescription = $" {model.CreatedByName} has deleted the <b>HWC</b> <strong>{model.HWCName}</strong>."
                        };
                        await this.auditLogServices.LogAsync(auditLogModel);
                    }
                }
                catch (Exception)
                {
                    // ignore
                }
                return this.Success(response);
            }
            catch (Exception)
            {
                return this.Success(-3);
            }
        }
    }
}