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

    using Domain.Services;

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.UserModels;
    using Shared.UserModels.Pharmacy;
    using Shared.UserModels.ExcelUploads;
    using Shared.Library.Enums;

    using Utilities;
    using Hims.Api.Models;
    using Hims.Shared.UserModels.UserExcel;
    using Hims.Infrastructure.Services;
    using Hims.Shared.UserModels.Filters;

    /// <summary>
    /// The user excel history controller.
    /// </summary>
    [Authorize]
    [Route("api/user-import")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class UserExcelHistoryController : BaseController
    {
        /// <summary>
        /// The excel upload history service.
        /// </summary>
        private readonly IUserExcelHistoryService userExcelHistoryService;

        /// <summary>
        /// The user service.
        /// </summary>
        private readonly IUserService usersServices;
        /// <summary>
        /// The audit log services.
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <inheritdoc />
        public UserExcelHistoryController(

            IUserExcelHistoryService userExcelHistoryService,
            IUserService usersServices,
            IAuditLogService auditLogServices)
        {
            this.userExcelHistoryService = userExcelHistoryService;
            this.usersServices = usersServices;
            this.auditLogServices = auditLogServices;
        }

        /// <summary>
        /// The add products from excel async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("add-user-sheet")]
        public async Task<ActionResult> AddUserFromExcelAsync([FromBody] UserExcelHistoryModel model, [FromHeader] LocationHeader header)
        {
            model = (UserExcelHistoryModel)EmptyFilter.Handler(model);
            var response = 0;

            if (model.Users.Count == 0)
            {
                return this.ServerError("Invalid sheet");              
            }
            var (userList, unMatchedList) = await this.AddUserAsync(model);
            if (userList.Count > 0)
            {
                var excelHistory = new UserExcelHistoryModel
                {
                    UserExcelHistoryId = model.UserExcelHistoryId,
                    SheetName = model.SheetName,
                    //SheetType = "User Excel Sheet",
                    UploadedBy = model.CreatedBy,
                    AddedUsers = string.Join(",", userList.Select(m => m.UserId)),
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                response = await this.userExcelHistoryService.ModifyExcelUploadAsync(excelHistory);
            }
            if(response > 0)
            {
                var auditLog = new AuditLogModel
                {
                    AccountId = model.CreatedBy,
                    LogTypeId = (int)LogTypes.ExcelSheet,
                    LogFrom = (short)model.RoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $@"{model.UploadedByName} has uploaded {model.SheetName} on {DateTime.UtcNow.AddMinutes(330).ToString("MM/dd/yyyy hh:mm tt")}",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLog);
            }
            return this.Success(new Tuple<int, List<RawUserModel>>(response, unMatchedList ?? new List<RawUserModel>()));
        }


        /// <summary>
        /// The fetch all excel upload history.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("fetch-upload-history")]
        public async Task<ActionResult> FetchAllExcelUploadHistory([FromBody] UserExcelHistoryModel model)
        {
            model = (UserExcelHistoryModel)EmptyFilter.Handler(model);
            var response = await this.userExcelHistoryService.FetchAllAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// The fetch all excel users async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Route("fetch-uploaded-users")]
        public async Task<ActionResult> FetchAllExcelUsersAsync([FromBody] UserExcelHistoryModel model)
        {
            model = (UserExcelHistoryModel)EmptyFilter.Handler(model);
            var response = (await this.usersServices.FetchAllAsync(new UserFilterModel { BulkUserIds = model.AddedUsers })).ToList();
            var userArray = model.AddedUsers.Split(",");
            var userList = new List<UserModel>();
            for (int i = 0; i < userArray.Length; i++)
            {
                var userId = int.Parse(userArray[i]);
                var user = response.Find(m => m.UserId == userId);
                userList.Add(user);
            }
            return this.Success(userList);
        }

        /// <summary>
        /// The add pharmacy product async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        private async Task<Tuple<List<UserModel>, List<RawUserModel>>> AddUserAsync(UserExcelHistoryModel model)
        {
            var totalUserList = new List<UserModel>();
            var returnModel = new List<RawUserModel>();
            foreach (var user in model.Users)
            {
                var singleUser = new UserModel();
                user.FullName = CoreFilter.FullName(user.FirstName, user.MiddleName, user.LastName);
                singleUser.FirstName = user.FirstName;
                singleUser.MiddleName = user.MiddleName;
                singleUser.LastName = user.LastName;
                singleUser.FullName = user.FullName;
                singleUser.Email = user.Email;
                singleUser.AddressLine = user.Address;
                singleUser.Gender = char.Parse(user.Gender);
                singleUser.EmployeeCode = user.EmployeeCode;
                singleUser.Mobile = user.Mobile;
                singleUser.UserName = user.UserName;
                singleUser.CreatedBy = model.CreatedBy;
                singleUser.RoleId = user.RoleId;
                singleUser.LocationIds = user.LocationId;
                singleUser.CountryId = 1;
                var (accountId, userId, guid) = await this.usersServices.AddFtpAsync(singleUser);
                if (accountId < 0)
                {
                    returnModel.Add(user);
                    
                }
                else
                {
                    singleUser.UserId = userId;
                    totalUserList.Add(singleUser);
                }
            }
            return new Tuple<List<UserModel>, List<RawUserModel>>(totalUserList, returnModel);
        }

    }
}
