using LHDN.CRM.BC.Common;
using LHDN.CRM.BC.Services;
using LHDN.CRM.Models.ViewModels;
using LHDN.CRM.WebAPI.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Caching;
using System.Web;
using System.Web.Http;
using System.Transactions;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;

namespace LHDN.CRM.WebAPI.Controllers.Api
{
    public class UserApiController : BaseApiController
    {
        private UserProfileService userSVC = new UserProfileService();
        private EmailService emailSvc = new EmailService();

        [HttpGet]
        [ApiErrorHandler]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult GetUserRoleListing()
        {
            int intCount = 0;

            var lst = userSVC.GetUserRoleListing();

            return Json(lst);

        }

        [HttpPost]
        [ApiErrorHandler]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult GetUserRoleMatrix()
        {
            int intCount = 0;

            var lst = userSVC.GetUserRoleMatrix();


            return Json(lst);

        }


        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult GetUserGroupHierarcyOptions()
        {
            var lst = userSVC.GetUserGroupHierarcyOptions();

            return Json(lst);

        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult SearchUserByUnitID(int iUnitID)
        {
            var lst = userSVC.SearchUserByUnitID(iUnitID);

            return Json(lst);

        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult GetDefaultManager()
        {
            WorkflowUserViewModel manager = new WorkflowUserViewModel();
            if (userSVC.Manager == null)
            {
                manager.ID = null;
                manager.DisplayName = "No assigned manager";
            }
            else
            {
                manager = userSVC.Manager;
            }
            return Json(manager);
        }

        [HttpGet]
        public IHttpActionResult SearchUserByName(string strName)
        {
            return Json(userSVC.SearchUserByName(strName));
        }

        [HttpGet]
        public IHttpActionResult SearchUnitByName(string strName)
        {
            return Json(userSVC.SearchUnitByName(strName));
        }


        [HttpPost]
        [ApiErrorHandler]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult GetFuncTaskList(int intFunctionalRoleId)
        {
            var lst = userSVC.GetFuncTaskList(intFunctionalRoleId);

            return Json(lst);
        }

        [HttpGet]
        [ApiErrorHandler]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult GetUserRoleDetails(int intFunctionalRoleId)
        {
            var lst = userSVC.GetUserRoleDetails(intFunctionalRoleId);

            return Json(lst);
        }


        [HttpPost]
        [ApiErrorHandler]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult SaveRoleDetails(UserRoleDetailViewModel roleDetails)
        {
            int intFunctionalRoleID = 0;
            string strLastUpdatedBy = userSVC.LoginID;
            DateTime dtNow = DateTime.Now;
            bool blnIsUpdate = false;
            AuditService.ActionType actionType = AuditService.ActionType.Add;
            string strText = "Manage User Role Details : " + roleDetails.RoleName;

            if (roleDetails.FunctionalRoleID != 0)
            {
                blnIsUpdate = true;
                actionType = AuditService.ActionType.Update;
            }
            UserCacheViewModel objUserNameCache = new UserCacheViewModel();
            var data = userSVC.SaveRoleDetails(roleDetails, blnIsUpdate, strLastUpdatedBy, dtNow, out intFunctionalRoleID, out objUserNameCache);

            //if (objUserNameCache != null) {
            //    UpdateCache(objUserNameCache);
            //}

            if (intFunctionalRoleID != 0)
            {
                AuditLogTxn(AuditService.AuditEventID.CreateUpdateUserRole,
                AuditService.ResultType.Success,
                actionType,
                userSVC.LoginID,
                dtNow,
                strText,
                data,
                "Usr_FunctionalRole", roleDetails.FunctionalRoleID);
            }

            return Json(intFunctionalRoleID);
        }

        [HttpPost]
        [ApiErrorHandler]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Administration.ManageUserRole)]
        public IHttpActionResult FindDuplicateRoleName(UserRoleDetailViewModel roleDetail)
        {
            return Json(userSVC.FindDuplicateRoleName(roleDetail));
        }

        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult SearchUsersByKeyword(PeoplePickerViewModel obj)
        {
            return Json(userSVC.SearchUsersByKeyword(obj));
        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult SearchRoleByName(string strName)
        {
            return Json(userSVC.SearchRoleByName(strName));
        }
        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult GetAdminUserProfileList(UserProfilePagedListViewModel paging)
        {

            int intCount = 0;
            var lst = userSVC.GetUserProfileList(paging, out intCount);

            DTResultViewModel<UserProfileViewModel> objRecord = null;

            objRecord = new DTResultViewModel<UserProfileViewModel>()
            {
                draw = paging.Draw,
                recordsTotal = intCount, //data.Count,
                recordsFiltered = intCount, //data.Count,
                data = lst
            };

            return Json(objRecord);

        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult GetUserProfileDetailByID(int intUserProfileId)
        {
            var lst = userSVC.GetUserProfileDetailsByID(intUserProfileId);

            return Json(lst);
        }

        [HttpPost]
        [ApiErrorHandler]
        [ValidateAjaxRequest]
        public IHttpActionResult UpdateUserProfileDetail(UserProfileUpdateViewModel model)
        {
            model.UserProfile.LastUpdatedBy = userSVC.LoginID;
            model.UserProfile.LastUpdatedDateTime = DateTime.Now;
            string strDirectManagerEmail = "";

            if (model.UserProfile.UserProfileID == 0)
            {
                model.UserProfile.CreatedBy = userSVC.LoginID;
                model.UserProfile.CreatedDateTime = DateTime.Now;
            }

            var data = userSVC.UpdateUserProfileDetail(model, out strDirectManagerEmail);

            AuditService.AuditEventID auditEvent = new AuditService.AuditEventID();
            AuditService.ActionType actionType = new AuditService.ActionType();
            List<AuditDetailViewModel> lstAuditDetail = null;

            auditEvent = AuditService.AuditEventID.AssignBackOffice;
            actionType = AuditService.ActionType.Update;
            lstAuditDetail = data.ChangeHistory.Select(a => new AuditDetailViewModel
            {
                FieldName = a.DisplayName,
                OldValue = a.OldValue,
                NewValue = a.NewValue
            }).ToArray().ToList();

            AuditLogTxn(auditEvent,
                        AuditService.ResultType.Success,
                        actionType,
                        userSVC.LoginID,
                        DateTime.Now,
                        "Update User Profile Detail. User Profile Detail ID =" + data.UserProfile.UserProfileID,
                        lstAuditDetail,
                        "Usr_UserProfile",
                        data.UserProfile.UserProfileID);

            if(strDirectManagerEmail !="")
            {
                string strAssignToEmail = string.Empty;
                DateTime dttime = DateTime.Now;
                EmailService svc = new EmailService();
                List<string> lstEmailTo = new List<string>();
                List<string> lstEmailCC = new List<string>();

                strAssignToEmail = strDirectManagerEmail;

                if (strAssignToEmail != "")
                {
                    lstEmailTo.Add(strAssignToEmail);
                    svc.SendEmailNotification(lstEmailTo, lstEmailCC, (int)Constant.EmailTemplate.EscalateToDirectManager, model.UserProfile.LastUpdatedBy, model.UserProfile.UserProfileID, dttime);
                }
            }

            return Json(data);
        }


        [HttpGet]
        [ValidateAjaxRequest]
        public IHttpActionResult SearchReportingManagerByName(string strName)
        {
            return Json(userSVC.SearchUserByName(strName));
        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult SearchUnitTypeByName(string strName)
        {
            return Json(userSVC.SearchUnitTypeByName(strName));
        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult GetUserRequestProfileDetailByID(int intWFUserProfileId)
        {
            var lst = userSVC.GetUserRequestProfileDetailByID(intWFUserProfileId, userSVC.UserInfo);

            return Json(lst);
        }

        [HttpPost]
        [ApiErrorHandler]
        [ValidateAjaxRequest]
        public IHttpActionResult UpdateWFUserProfileDetail(UserRequestProfileUpdateViewModel model)
        {
            model.WFUserProfile.LastUpdatedBy = userSVC.LoginID;
            model.WFUserProfile.LastUpdatedByName = userSVC.DisplayName;
            model.WFUserProfile.LastUpdatedByEmail = userSVC.Email;
            model.WFUserProfile.LastUpdatedDateTime = DateTime.Now;
            model.WFUserProfile.CurrentUserUnitID = userSVC.UnitID;
            model.WFUserProfile.CurrentUserUnitName = userSVC.UnitName;
            string strAssignToEmail = string.Empty;


            if (model.WFUserProfile.WFUserProfileID == 0)
            {
                model.WFUserProfile.CreatedBy = userSVC.LoginID;
                model.WFUserProfile.CreatedByName = userSVC.DisplayName;
                model.WFUserProfile.CreatedByEmail = userSVC.Email;
                model.WFUserProfile.CreatedDateTime = DateTime.Now;
            }

            var data = userSVC.UpdateWorkflowUserProfileDetail(model, out strAssignToEmail, userSVC.UserInfo);

            if (data.WFUserProfile.WFUserProfileID > 0)
            {
                AuditService.AuditEventID auditEvent = new AuditService.AuditEventID();
                AuditService.ActionType actionType = new AuditService.ActionType();
                List<AuditDetailViewModel> lstAuditDetail = null;

                auditEvent = AuditService.AuditEventID.AssignBackOffice;
                actionType = AuditService.ActionType.Update;
                lstAuditDetail = data.ChangeHistory.Select(a => new AuditDetailViewModel
                {
                    FieldName = a.DisplayName,
                    OldValue = a.OldValue,
                    NewValue = a.NewValue
                }).ToArray().ToList();

                AuditLogTxn(auditEvent,
                            AuditService.ResultType.Success,
                            actionType,
                            userSVC.LoginID,
                            DateTime.Now,
                            "Update Workflow User Profile Detail. WF User Profile Detail ID =" + data.WFUserProfile.WFUserProfileID,
                            lstAuditDetail,
                            "Usr_WFUserProfile",
                            data.WFUserProfile.WFUserProfileID);

                #region Send Email Function
                if (strAssignToEmail != "")
                {
                    strAssignToEmail = strAssignToEmail.TrimEnd(',');
                    List<string> lstEmailTo = new List<string>();
                    List<string> lstEmailCC = new List<string>();
                    lstEmailTo.Add(strAssignToEmail);
                    long i = emailSvc.SendEmailNotification(lstEmailTo, lstEmailCC, (int)Constant.EmailTemplate.UserProfileWFNotification, model.WFUserProfile.CreatedBy, data.WFUserProfile.WFUserProfileID, model.WFUserProfile.LastUpdatedDateTime);
                }
                #endregion
            }

            return Json(data);
        }


        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult GetWorkflowUserProfileList(WorkflowUserProfilePagedListViewModel paging)
        {

            int intCount = 0;
            var lst = userSVC.GetWorkflowUserProfileList(paging, out intCount);

            DTResultViewModel<UserRequestProfileViewModel> objRecord = null;

            objRecord = new DTResultViewModel<UserRequestProfileViewModel>()
            {
                draw = paging.Draw,
                recordsTotal = intCount, //data.Count,
                recordsFiltered = intCount, //data.Count,
                data = lst
            };

            return Json(objRecord);

        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult CheckDuplicateLogin(string sUserLoginID)
        {
            var lst = userSVC.CheckDuplicateByLoginID(sUserLoginID);

            return Json(lst);

        }

        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult GetUserFromAD(string strEmail)
        {
            return Json(userSVC.GetUserFromAD(strEmail));
        }


        [HttpGet]
        [ApiErrorHandler]
        public IHttpActionResult CheckWFUserDuplicateLogin(string sUserLoginID)
        {
            var lst = userSVC.CheckWFUserDuplicateLogin(sUserLoginID);

            return Json(lst);

        }

        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult GetDashboardMyPendingUserRequest(UserRequestDashboardViewModel paging)
        {
            string strAssignTo = userSVC.LoginID;
            int intCount = 0;
            var lst = userSVC.GetDashboardMyPendingUserRequest(strAssignTo, paging, out intCount);

            DTResultViewModel<UserRequestDashboardViewModel> objRecord = null;

            objRecord = new DTResultViewModel<UserRequestDashboardViewModel>()
            {
                draw = paging.Draw,
                recordsTotal = intCount,
                recordsFiltered = intCount,
                data = lst
            };

            return Json(objRecord);
        }

        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult GetDashboardMyCreatedUserRequest(UserRequestDashboardViewModel paging)
        {
            string strAssignFrom = userSVC.LoginID;
            int intCount = 0;
            var lst = userSVC.GetDashboardMyCreatedUserRequest(strAssignFrom, paging, out intCount);

            DTResultViewModel<UserRequestDashboardViewModel> objRecord = null;

            objRecord = new DTResultViewModel<UserRequestDashboardViewModel>()
            {
                draw = paging.Draw,
                recordsTotal = intCount,
                recordsFiltered = intCount,
                data = lst
            };

            return Json(objRecord);
        }

        [HttpPost]
        [ApiErrorHandler]
        public IHttpActionResult CancelRequestWFUserProfile(UserRequestProfileUpdateViewModel model)
        {
            model.WFUserProfile.LastUpdatedBy = userSVC.LoginID;
            model.WFUserProfile.LastUpdatedByName = userSVC.DisplayName;
            model.WFUserProfile.LastUpdatedByEmail = userSVC.Email;
            model.WFUserProfile.LastUpdatedDateTime = DateTime.Now;

            var data = userSVC.CancelRequestWFUserProfile(model);

            return Json(data);
        }

        [HttpGet]
        public IHttpActionResult SearchUserRequestUnitByName(string strName,long lgWFUserProfileID)
        {
            var UnitID = userSVC.UnitID;
            return Json(userSVC.SearchUserRequestUnitByName(strName, UnitID, lgWFUserProfileID));
        }
    }
}