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

    using Domain.Services;
    using Hims.Shared.Library.Enums;
    using Hims.Shared.UserModels.Common;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Shared.DataFilters;
    using Shared.EntityModels;

    using Utilities;

    /// <inheritdoc />
    [Authorize]
    [Route("api/company")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class CompanyController : BaseController
    {
        /// <summary>
        /// The company service.
        /// </summary>
        private readonly ICompanyService companyService;

        /// <summary>
        /// The pharmacy service.
        /// </summary>
        private readonly IPharmacyLogService pharmacyLogService;

        /// <summary>
        /// The Inventory log services.
        /// </summary>
        private readonly IInventoryLogService inventoryLogServices;

        /// <inheritdoc />
        public CompanyController(ICompanyService companyService, IPharmacyLogService pharmacyLogService, IInventoryLogService inventoryLogServices)
        {
            this.companyService = companyService;
            this.pharmacyLogService = pharmacyLogService;
            this.inventoryLogServices = inventoryLogServices;
        }
        /// <summary>
        /// The create async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("add")]
        public async Task<ActionResult> CreateAsync([FromBody] CompanyModel model)
        {
            model = (CompanyModel)EmptyFilter.Handler(model);
            var response = await this.companyService.InsertCompanyAsync(model);

            if (model.TypeOf == "pharmacyCompany")
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.LoginAccountId,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Pharmacy_Masters_Company,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow,
                    LogDescription = $@"New Company Added Successfully<br/>Name: '{model.Name}'<br/>Location: '{model.Location}'"
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
            }
            else
            {
                if (model.TypeOf == "inventoryCompany")
                {
                    try
                    {
                        var iLogs = new InventoryLogModel
                        {
                            AccountId = model.LoginAccountId,
                            InventoryLogTypeId = (int)InventoryLogTypes.Company,
                            LogFrom = (short)model.LoginRoleId,
                            LogDate = DateTime.UtcNow.AddMinutes(330),
                            LogDescription = $@"New Company <b>{model.Name}</b>, <i>@</i><b>{model.Location}</b> Successfully <b>Added</b>."
                        };
                        await this.inventoryLogServices.LogAsync(iLogs);
                    }
                    catch (Exception e)
                    {
                        //logs
                    }
                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// The fetch async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch")]
        public async Task<ActionResult> FetchAllAsync([FromBody] CompanyFilterModel model)
        {
            model = (CompanyFilterModel)EmptyFilter.Handler(model);
            var response = await this.companyService.FetchAllAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// The update supplier async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Route("update")]
        public async Task<ActionResult> UpdateAsync([FromBody] CompanyModel model)
        {
            model = (CompanyModel)EmptyFilter.Handler(model);
            var response = await this.companyService.UpdateCompanyAsync(model);

            if (model.TypeOf == "pharmacyCompany")
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.LoginAccountId,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Pharmacy_Masters_Company,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow,
                    LogDescription = $@"Company Details Updated Successfully<br/>Name: '{model.Name}'<br/>Location: '{model.Location}'"
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
            }
            else
            {
                if (model.TypeOf == "inventoryCompany")
                {
                    try
                    {
                        var iLogs = new InventoryLogModel
                        {
                            AccountId = model.LoginAccountId,
                            InventoryLogTypeId = (int)InventoryLogTypes.Company,
                            LogFrom = (short)model.LoginRoleId,
                            LogDate = DateTime.UtcNow.AddMinutes(330),
                            LogDescription = $@"Company <b>{model.Name}</b>, <i>@</i><b>{model.Location}</b> Successfully <b>Updated</b>."
                        };
                        await this.inventoryLogServices.LogAsync(iLogs);
                    }
                    catch (Exception e)
                    {
                        //logs
                    }

                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// The delete async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("delete")]
        public async Task<ActionResult> DeleteAsync([FromBody] CompanyModel model)
        {
            model = (CompanyModel)EmptyFilter.Handler(model);
            try
            {
                var response = await this.companyService.DeleteCompanyAsync(model.CompanyId);

                if (model.TypeOf == "pharmacyCompany")
                {
                    var pharmacyLogModel = new PharmacyLogModel
                    {
                        AccountId = model.LoginAccountId,
                        PharmacyLogTypeId = (int)PharmacyLogTypes.Pharmacy_Masters_Company,
                        LogFrom = (short)model.LoginRoleId,
                        LogDate = DateTime.UtcNow,
                        LogDescription = $@"Company Deleted Successfully<br/>Name: '{model.Name}'<br/>Location: '{model.Location}'"
                    };
                    await this.pharmacyLogService.LogAsync(pharmacyLogModel);
                }
                else
                {
                    if (model.TypeOf == "inventoryCompany")
                    {
                        try
                        {
                            var iLogs = new InventoryLogModel
                            {
                                AccountId = model.LoginAccountId,
                                InventoryLogTypeId = (int)InventoryLogTypes.Company,
                                LogFrom = (short)model.LoginRoleId,
                                LogDate = DateTime.UtcNow.AddMinutes(330),
                                LogDescription = $@"Company <b>{model.Name}</b>, <i>@</i><b>{model.Location}</b> Successfully <b>Deleted</b>."
                            };
                            await this.inventoryLogServices.LogAsync(iLogs);
                        }
                        catch (Exception)
                        {
                            //logs
                        }

                    }
                }
                return this.Success(new GenericResponse
                {
                    Status = response > 0 ? GenericStatus.Success : GenericStatus.Warning
                });
            }
            catch (Exception ex)
            {
                if (model.TypeOf == "inventoryCompany")
                {
                    if (ex.Message.Contains("update or delete on table \"Company\" violates foreign key constraint \"InventoryProduct_CompanyId_fkey\" on table \"InventoryProduct\""))
                    {
                        return this.Success(new GenericResponse
                        {
                            Status = GenericStatus.Error,
                            Message = ex.Message
                        });
                    }
                }
                if (model.TypeOf == "pharmacyCompany")
                {
                    if (ex.Message.Contains("update or delete on table \"Company\" violates foreign key constraint \"PharmacyProduct_CompanyId_fkey\" on table \"PharmacyProduct\""))
                    {
                        return this.Success(new GenericResponse
                        {
                            Status = GenericStatus.Error,
                            Message = ex.Message
                        });
                    }
                }
                throw;
            }

        }
    }
}