using LHDN.CRM.BC.Services;
using LHDN.CRM.Models.Models;
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.Web;
using System.Web.Http;
using LHDN.CRM.BC.Common;
using System.Data;
using System.Threading.Tasks;
using System.IO;
using System.Web.Http.Results;
using System.Net.Http.Headers;
using System.Transactions;

namespace LHDN.CRM.WebAPI.Controllers.Api
{
    [ApiErrorHandler]
    public class CaseApiController : BaseApiController
    {
        private BC.Services.CaseService svc = new BC.Services.CaseService();
        private BC.Services.ActivityService actSvc = new BC.Services.ActivityService();
        private BC.Services.EmailService emailSvc = new BC.Services.EmailService();
        private BC.Services.UserProfileService userSvc = new UserProfileService();
        private BC.Services.WorkflowService workflowsvc = new BC.Services.WorkflowService();

        [HttpGet]
        [CacheWebApi]
        [CRMAuthorize(Constant.Authentication.Cases.ViewCaseProfile)]
        public IHttpActionResult GetCase(long id)
        {
            CaseViewModel data = null;
            data = svc.GetById(id,userSvc.UserInfo);

            //if (data == null)
            //    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Case not found!"));

            DateTime dtNow = DateTime.Now;

            AuditLogTxn(AuditService.AuditEventID.ViewCaseProfile,
                AuditService.ResultType.Success,
                AuditService.ActionType.View,
                userSvc.LoginID,
                dtNow,
                string.Format(Constant.AuditAdditionalInfo.Case, userSvc.DisplayName, userSvc.LoginID, id),
                null, "Case", id);

            return Json(data);
        }

        [HttpGet]
        public IHttpActionResult GetCaseSummary(long id)
        {
            return Json(svc.GetCaseSummary(id));
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetOpenCase(CasePagedListViewModel paging)
        {
            int intCount = 0;
            var lst = svc.GetOpenCase(paging, out intCount);
            DTResultViewModel<CaseViewModel> objRecord = null;

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

            return Json(objRecord);
        }

        [HttpPost()]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult AddCaseCatatan(CaseCatatanViewModel catatanVM)
        {
            DateTime dtNow = DateTime.Now;
            string strUserName = userSvc.DisplayName;
            string strUserID = userSvc.LoginID;

            long lngActCatatanID = svc.InsertCaseCatatan(catatanVM, strUserName, strUserID, dtNow);

            //get lstActCatatan
            var data = svc.GetAllCaseCatatan(catatanVM.CaseID, 0);

            AuditLogTxn(AuditService.AuditEventID.CreateUpdateCaseCatatan,
                        AuditService.ResultType.Success,
                        AuditService.ActionType.Add,
                        strUserID,
                        dtNow,
                        string.Format(Constant.AuditAdditionalInfo.CaseCatatan, strUserName, strUserID, catatanVM.CaseID, lngActCatatanID), 
                        null, "Case_Catatan", lngActCatatanID);

            return Json(data);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult UpdateCaseCatatan(CaseCatatanViewModel catatanVM)
        {
            DateTime dtNow = DateTime.Now;
            string strUserName = userSvc.DisplayName;
            string strUserID = userSvc.LoginID;

            List<ChangeHistoryUpdateViewModel> lstChangeHist = svc.UpdateCaseCatatan(catatanVM, strUserName, strUserID, dtNow);

            //get lstActCatatan
            var data = svc.GetAllCaseCatatan(catatanVM.CaseID, 0);

            AuditLogTxn(AuditService.AuditEventID.CreateUpdateCaseCatatan,
                            AuditService.ResultType.Success,
                            AuditService.ActionType.Update,
                            strUserID,
                            dtNow,
                            string.Format(Constant.AuditAdditionalInfo.CaseCatatan, strUserName, strUserID, catatanVM.CaseID, catatanVM.CatatanID),
                            lstChangeHist.Select(a => new AuditDetailViewModel
                            {
                                FieldName = a.DisplayName,
                                OldValue = a.OldValue,
                                NewValue = a.NewValue
                            }).ToList(), "Case_Catatan", catatanVM.CatatanID);

            return Json(data);
        }

        [HttpPost()]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult DeleteCaseCatatan(CaseCatatanViewModel catatanVM)
        {
            DateTime dtNow = DateTime.Now;
            string strUserName = userSvc.DisplayName;
            string strUserID = userSvc.LoginID;

            List<ChangeHistoryUpdateViewModel> lstChangeHist = svc.DeleteCaseCatatan(catatanVM, strUserName, strUserID, dtNow);

            //get lstActCatatan
            var data = svc.GetAllCaseCatatan(catatanVM.CaseID, 0);

            AuditLogTxn(AuditService.AuditEventID.CreateUpdateCaseCatatan,
                            AuditService.ResultType.Success,
                            AuditService.ActionType.Delete,
                            strUserID,
                            dtNow,
                            string.Format(Constant.AuditAdditionalInfo.CaseCatatan, strUserName, strUserID, catatanVM.CaseID, catatanVM.CatatanID),
                            lstChangeHist.Select(a => new AuditDetailViewModel
                            {
                                FieldName = a.DisplayName,
                                OldValue = a.OldValue,
                                NewValue = a.NewValue
                            }).ToList(), "Case_Catatan", catatanVM.CatatanID);

            return Json(data);

        }

        //[HttpPost]
        //[ValidateAjaxRequest]
        //public IHttpActionResult UpdateCaseCatatan2(CaseCatatanViewModel catatanVM)
        //{
        //    string strText = catatanVM.Indicator == 1 ? "Insert Case Catatan" : (catatanVM.Indicator == 2 ? "Update Case Catatan" : "Delete Case Catatan");
        //    var actionType = catatanVM.Indicator == 1 ? AuditService.ActionType.Add : (catatanVM.Indicator == 2 ? AuditService.ActionType.Update : AuditService.ActionType.Delete);

        //    DateTime dtNow = DateTime.Now;
        //    catatanVM.CreatedBy = userSvc.LoginID;
        //    catatanVM.CreatedByName = userSvc.DisplayName;
        //    catatanVM.LastUpdatedDateTime = dtNow;
        //    List<ChangeHistoryUpdateViewModel> lstChangeHist = new List<ChangeHistoryUpdateViewModel>();

        //    long lngCatatanID = svc.UpdateCaseCatatan(catatanVM, out lstChangeHist);

        //    if (catatanVM.Indicator == 2) //update
        //    {
        //        AuditLogTxn(AuditService.AuditEventID.CreateUpdateCaseCatatan,
        //                    AuditService.ResultType.Success,
        //                    AuditService.ActionType.Update,
        //                    userSvc.LoginID,
        //                    dtNow,
        //                    strText,
        //                    lstChangeHist.Select(a => new AuditDetailViewModel
        //                    {
        //                        FieldName = a.DisplayName,
        //                        OldValue = a.OldValue,
        //                        NewValue = a.NewValue
        //                    }).ToArray().ToList(),
        //                    "Case_Catatan", lngCatatanID);
        //    }
        //    else
        //    {
        //        AuditLogTxn(AuditService.AuditEventID.CreateUpdateCaseCatatan,
        //                    AuditService.ResultType.Success,
        //                    actionType,
        //                    userSvc.LoginID,
        //                    dtNow,
        //                    strText,
        //                    null,
        //                    "Case_Catatan", lngCatatanID);
        //    }

        //    return Json(svc.GetAllCaseCatatan(catatanVM.CaseID, 0));
        //}

        [HttpPost()]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public async Task<IHttpActionResult> UploadAttachment()
        {

            if (!Request.Content.IsMimeMultipartContent())
            {
                //throw new UnsupportedMediaTypeException( );
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            TempAttachmentViewModel a = new TempAttachmentViewModel();
            DateTime dtNow = DateTime.Now;

            if (HttpContext.Current.Request.Files.Count > 0)
            {
                var streamProvider = new MultipartMemoryStreamProvider();
                await Request.Content.ReadAsMultipartAsync(streamProvider);
                foreach (HttpContent item in streamProvider.Contents)
                {
                    string strFileName = item.Headers.ContentDisposition.FileName.Replace("\"", String.Empty);
                    byte[] yArrFileContent = item.ReadAsByteArrayAsync().Result;
                    a.FileName = strFileName;
                    a.FileContent = yArrFileContent;
                    a.FileContentType = MimeMapping.GetMimeMapping(strFileName); //Path.GetExtension(strFileName); 
                    a.CreatedDateTime = dtNow;
                }
            }

            var data = svc.InsertTempAttachment(a);

            return Json(data);
        }

        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult GetAttachment(string type, long id)
        {
            //id -- AttachmentID //type -- Attachment Table
            DataTable data = svc.GetAttachment(type, id);
            string strFileName = string.Empty;
            string strContentType = string.Empty;
            byte[] FileContent = new byte[0];

            if (data == null || data.Rows.Count == 0)
            {

                throw new HttpResponseException(HttpStatusCode.NoContent);
            }

            strFileName = data.Rows[0][0].ToString();
            strContentType = data.Rows[0][1].ToString();
            FileContent = (byte[])data.Rows[0][2];

            MemoryStream stream = new MemoryStream(FileContent);

            HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(stream)
            };

            httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = strFileName
            };


            httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(strContentType);

            ResponseMessageResult responseMessageResult = ResponseMessage(httpResponseMessage);
            return responseMessageResult;
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult DeleteAttachment([FromBody]long TempAttachmentID)
        {
            svc.DeleteTempAttachment(TempAttachmentID);

            return Ok();
        }

        [HttpGet]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan, Constant.Authentication.Cases.CreateUpdateCase)]
        public IHttpActionResult GetAllCaseCatatan(long id) //Special for ActivityCatatan (Transfer to Case use)
        {
            return Json(svc.GetAllCaseCatatan(0, id));
        }

        [HttpGet]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCatatan)]
        public IHttpActionResult GetAllCatatanInString(long id)
        {
            return Json(svc.GetAllCatatanInString(id, 0));
        }

        [HttpGet]
        [CRMAuthorize(Constant.Authentication.Cases.ViewCaseProfile)]
        public IHttpActionResult GetCaseDropdown()
        {
            return Json(svc.GetCaseDropdown(userSvc.RoleTindakanSusulan));
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.CreateUpdateCase)]
        public IHttpActionResult UpdateCase(CaseUpdateViewModel caseUpdateVM)
        {
            long lngCaseID = CreateCase(caseUpdateVM);
            return Json(lngCaseID);
        }

        public long CreateCase(CaseUpdateViewModel caseUpdateVM)
        {
            DataTable dTblResult = new DataTable();
            string strLastUpdatedBy = caseUpdateVM.IsCFFDraft == true ? Constant.System.Name : userSvc.LoginID;
            string strLastUpdatedName = caseUpdateVM.IsCFFDraft == true ? Constant.System.Name : userSvc.DisplayName;
            string strEmail = caseUpdateVM.IsCFFDraft == true ? AdminService.ParameterSettings.Where(x => x.ParameterID == 5).FirstOrDefault().ParameterValue : userSvc.Email;
            DateTime dtNow = DateTime.Now;
            List<ChangeHistoryUpdateViewModel> data = new List<ChangeHistoryUpdateViewModel>();
            long lngCaseID = 0;
            string strCaseRefNo = "";
            string strDescription = "";
            AuditService.AuditEventID auditEvent = new AuditService.AuditEventID();
            AuditService.ActionType actionType = new AuditService.ActionType();
            List<AuditDetailViewModel> lstAuditDetail = null;
            
            caseUpdateVM.Case.LastUpdatedBy = strLastUpdatedBy;
            caseUpdateVM.Case.LastUpdatedByName = strLastUpdatedName;
            caseUpdateVM.Case.LastUpdatedDateTime = dtNow;
            //caseUpdateVM.Case.AssignedToEmail = strEmail;

            if (caseUpdateVM.Case.CaseID == 0) //INSERT CASE
            {
                //IF CFF
                //if (caseUpdateVM.IsCFFDraft)
                //{
                //    caseUpdateVM.Case.LastUpdatedBy = Constant.System.Name;
                //    caseUpdateVM.Case.LastUpdatedByName = Constant.System.Name;
                //    caseUpdateVM.Case.AssignedToEmail = AdminService.ParameterSettings.Where(x => x.ParameterID == 5).FirstOrDefault().ParameterValue; 
                //}
                caseUpdateVM.Case.CreatedDateTime = dtNow;
                data = svc.InsertCase(caseUpdateVM, out lngCaseID, out strCaseRefNo, userSvc.UserInfo);
                auditEvent = AuditService.AuditEventID.TransfertoCase;
                actionType = AuditService.ActionType.Add;
                strDescription = string.Format(Constant.RecentActivity.CaseCreatedMsg, strCaseRefNo);
            }
            else if (caseUpdateVM.Case.CaseID > 0) //UPDATE CASE
            {
                data = svc.UpdateCase(caseUpdateVM, out lngCaseID, out strCaseRefNo, userSvc.UserInfo);
                auditEvent = AuditService.AuditEventID.CreateUpdateCaseProfile;
                actionType = AuditService.ActionType.Update;
                lstAuditDetail = data.Select(a => new AuditDetailViewModel
                {
                    FieldName = a.DisplayName,
                    OldValue = a.OldValue,
                    NewValue = a.NewValue
                }).ToArray().ToList();

                if ((bool)caseUpdateVM.Case.IsCaseClosed && (int)caseUpdateVM.Case.CaseStatusLevel1ID == (int)Constant.StatusLevel1.Selesai)
                {
                    auditEvent = AuditService.AuditEventID.CloseCase;
                    strDescription = string.Format(Constant.RecentActivity.CaseClosedMsg, strCaseRefNo);
                }
                else
                    strDescription = string.Format(Constant.RecentActivity.CaseUpdatedMsg, strCaseRefNo);
            }

            if (Convert.ToBoolean(Utilities.GetAppSetting("IntegrateWithCFF")))
            {
                // CFF Case & Inbound
                int inboundID = AdminService.LookupParams.Where(x => x.LookupCode == "Aliran" && x.IsActive == true && x.LookupValue == Constant.Aliran.Inbound).FirstOrDefault().LookupParamID;
                // If Case Closed - Integrate with Kube - HttpClient to call CFF.WebApi
                if (caseUpdateVM.Case.ActChannelID == (int)Constant.ActChannel.CFF && caseUpdateVM.Case.AliranID == inboundID && (bool)caseUpdateVM.Case.IsCaseClosed)
                {
                    List<long> lstCFFFormID = svc.GetCFFListByCaseID(lngCaseID);
                    lstCFFFormID.RemoveAll(x => x == 0);
                    CRMUpdateFieldViewModel cffUpdate = new CRMUpdateFieldViewModel();
                    cffUpdate.CFFFormIDList = lstCFFFormID;
                    cffUpdate.CRMLastUpdatedDate = dtNow;
                    cffUpdate.CRMStatus = Constant.Status.Selesai;

                    //HttpClient to call CFF.WebApi
                    //UpdateField(cffUpdate);

                    actSvc.InsertCFFQueue(cffUpdate, strLastUpdatedBy);
                }
            }

            AuditLogTxn(auditEvent,
                        AuditService.ResultType.Success,
                        actionType,
                        strLastUpdatedBy,
                        dtNow,
                        string.Format(Constant.AuditAdditionalInfo.Case, strLastUpdatedName, strLastUpdatedBy, lngCaseID),
                        lstAuditDetail,
                        "Case", lngCaseID);

            // Insert Recent Activity
            RecentActivityTxn("Case", lngCaseID, strDescription, strLastUpdatedBy, strLastUpdatedName, dtNow, string.Format(Constant.RecentActivity.CaseURL, lngCaseID));

            return lngCaseID;
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.Reopencase)]
        public IHttpActionResult ReopenCase(EntityUpdateViewModel model)
        {
            string strUserName = userSvc.DisplayName;
            string strUserID = userSvc.LoginID;
            DateTime dtNow = DateTime.Now;
            byte[] changeStamp = svc.ReopenCase(model, strUserName, strUserID, userSvc.UserInfo, dtNow);

            // TODO : Transaction Scope
            AuditLogTxn(AuditService.AuditEventID.ReopenCase, //TODO Audit EnventID for Delete Activity
                        AuditService.ResultType.Success,
                        AuditService.ActionType.Update,
                        userSvc.LoginID,
                        dtNow,
                        string.Format(Constant.AuditAdditionalInfo.Case, strUserName, strUserID, model.CaseID),
                        null, "Case", model.CaseID);

            // Insert Recent Activity
            RecentActivityTxn("Case", (long)model.CaseID, string.Format(Constant.RecentActivity.CaseReopenMsg, model.CaseRefNo), strUserID, strUserName, dtNow, string.Format(Constant.RecentActivity.CaseURL, model.CaseID));

            return Json(new { ChangeStamp = changeStamp });
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.DeleteCase)]
        public IHttpActionResult DeleteCase(EntityUpdateViewModel model)
        {
            string strLastUpdatedBy = userSvc.LoginID;
            string strLastUpdatedByName = userSvc.DisplayName;
            DateTime dtNow = DateTime.Now;
            bool data = false;
            DataTable dtblLinkedActivity = null;
            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                data = svc.DeleteCase(model, strLastUpdatedBy, strLastUpdatedByName, dtNow, out dtblLinkedActivity);

                if (data)
                {
                    // TODO : Transaction Scope
                    AuditLogTxn(AuditService.AuditEventID.DeleteCase,
                                AuditService.ResultType.Success,
                                AuditService.ActionType.Delete,
                                userSvc.LoginID,
                                dtNow,
                                string.Format(Constant.AuditAdditionalInfo.Case, strLastUpdatedByName, strLastUpdatedBy, model.CaseID,
                                null, "Case", model.CaseID));

                    // Insert Recent Activity
                    RecentActivityTxn("Case", (long)model.CaseID, string.Format(Constant.RecentActivity.CaseDeletedMsg, model.CaseRefNo), strLastUpdatedBy, strLastUpdatedByName, dtNow, string.Format(Constant.RecentActivity.CaseURL, model.CaseID));
                }

                if (dtblLinkedActivity != null && dtblLinkedActivity.Rows.Count > 0)
                {

                    for (var i = 0; i < dtblLinkedActivity.Rows.Count; i++)
                    {
                        long ActivityID = (long)dtblLinkedActivity.Rows[i][0];
                        model.ActivityID = ActivityID;
                        model.IsLinkCase = false;
                        List<ChangeHistoryUpdateViewModel> lstChangeHistory = null;
                        var vmAct = new ActivityViewModel();
                        byte[] arrActChangeStamp = null;
                        bool blnIsSuccess = actSvc.LinkUnlinkActivity(model, strLastUpdatedByName, strLastUpdatedBy, dtNow, out vmAct, out lstChangeHistory, out arrActChangeStamp, true);
                        if (blnIsSuccess)
                        {
                            AuditLogTxn(AuditService.AuditEventID.CreateUpdateActivityProfile,  //TODO Audit EnventID for Delete Activity
                                   AuditService.ResultType.Success,
                                   AuditService.ActionType.Update,
                                   userSvc.LoginID,
                                   dtNow,
                                   "Link/Unlink Case from Activity",
                                     new AuditDetailViewModel[1].Select(h => new AuditDetailViewModel()
                                     {
                                         FieldName = "Case No.",
                                         OldValue = (model.IsLinkCase == true) ? "" : model.CaseRefNo,
                                         NewValue = (model.IsLinkCase == true) ? model.CaseRefNo : ""
                                     }).ToList(), "Activity", model.ActivityID);

                            if (lstChangeHistory != null)
                            {
                                AuditLogTxn(AuditService.AuditEventID.CreateUpdateActivityProfile,
                                   AuditService.ResultType.Success,
                                   AuditService.ActionType.Update,
                                   userSvc.LoginID,
                                   dtNow,
                                   "Unlink Case from Activity: Update Activity details from Case",
                                    lstChangeHistory.Select(a => new AuditDetailViewModel
                                    {
                                        FieldName = a.DisplayName,
                                        OldValue = a.OldValue,
                                        NewValue = a.NewValue
                                    }).ToList(), "Activity", model.ActivityID);
                            }

                        }
                    }
                }

                scope.Complete();
            }
            return Json(data);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.AssignCase)]
        public IHttpActionResult InsertCaseWorkFlowAction(WorkflowUpdateViewModel workflowModel)
        {
            string strCreatedBy = userSvc.LoginID;
            string strLastUpdatedBy = userSvc.LoginID;
            string strCreatedByName = userSvc.DisplayName;
            string strLastUpdatedByName = userSvc.DisplayName;
            string strCurrentUserEmail = userSvc.Email;
            DateTime dtNow = DateTime.Now;
            WorkflowUserViewModel assignedUser = new WorkflowUserViewModel();
            string strDescription = "";
            string strCaseRefNo = "";
            DataTable dTblResult = new DataTable();
            bool blnAlertIsRead = false;
            string strActRefNo = "";
            string strAssignToEmail = string.Empty;

            workflowModel.Workflow.CreatedBy = strCreatedBy;
            workflowModel.Workflow.LastUpdatedBy = strLastUpdatedBy;
            workflowModel.Workflow.LastUpdatedByName = strLastUpdatedByName;
            workflowModel.Workflow.AssignBy = strCreatedBy;
            workflowModel.Workflow.AssignByName = strCreatedByName;
            workflowModel.Workflow.AssignByEmail = strCurrentUserEmail;
            workflowModel.Workflow.TableType = (int)Constant.TableType.Case;

            var data = workflowsvc.UpdateWorkflow(workflowModel, out strCaseRefNo,out strActRefNo, out dTblResult, ref assignedUser, dtNow);

            string strAction = "";
            string strMsg = "";
            if (data != null)
            {
                //Audit
                if (workflowModel.Workflow.DecisionID == (int)Constant.WorkFlow.WorkflowDecision.Assign)
                {
                    strAction = Constant.WorkFlow.WorkflowDecision.Assign.ToString();
                    strMsg = string.Format("{0} {1}", Constant.WorkFlow.WorkflowDecision.Assign.ToString(), " Case");
                    strDescription = string.Format(Constant.RecentActivity.CaseAssignmentCreatedMsg, strCaseRefNo);
                }
                else if (workflowModel.Workflow.DecisionID == (int)Constant.WorkFlow.WorkflowDecision.Recall)
                {
                    strAction = Constant.WorkFlow.WorkflowDecision.Recall.ToString();
                    strMsg = string.Format("{0} {1}", Constant.WorkFlow.WorkflowDecision.Recall.ToString(), " Case");
                    strDescription = string.Format(Constant.RecentActivity.CaseAssignmentRecallMsg, strCaseRefNo);
                }
                else if (workflowModel.Workflow.DecisionID == (int)Constant.WorkFlow.WorkflowDecision.Return)
                {
                    strAction = Constant.WorkFlow.WorkflowDecision.Return.ToString();
                    strMsg = string.Format("{0} {1}", Constant.WorkFlow.WorkflowDecision.Return.ToString(), " Case");
                    strDescription = string.Format(Constant.RecentActivity.CaseAssignmentReturnMsg, strCaseRefNo);
                }
                else
                {
                    strAction = Constant.WorkFlow.WorkflowDecision.Reassign.ToString();
                    strMsg = string.Format("{0} {1}", Constant.WorkFlow.WorkflowDecision.Reassign.ToString(), " Case");
                    strDescription = string.Format(Constant.RecentActivity.CaseAssignmentUpdatedMsg, strCaseRefNo);
                }

                AuditLogTxn(AuditService.AuditEventID.AssignBackOffice,
                    AuditService.ResultType.Success,
                    AuditService.ActionType.Update,
                    userSvc.LoginID,
                    dtNow, 
                    string.Format(Constant.AuditAdditionalInfo.CaseWorkflowAction, userSvc.DisplayName, userSvc.LoginID, workflowModel.Workflow.CaseID, strAction),
                    data.Select(a => new AuditDetailViewModel
                    {
                        FieldName = a.DisplayName,
                        OldValue = a.OldValue,
                        NewValue = a.NewValue
                    }).Cast<AuditDetailViewModel>().ToArray().ToList(),
                    "Workflow", workflowModel.Workflow.CaseID
                    );
            }

            // Insert Recent Activity
            RecentActivityTxn("Case Assignment", workflowModel.Workflow.CaseID, strDescription, workflowModel.Workflow.CreatedBy, workflowModel.Workflow.AssignByName, dtNow, string.Format(Constant.RecentActivity.CaseURL, workflowModel.Workflow.CaseID));

            if (dTblResult != null && dTblResult.Rows.Count > 0)
            {
                foreach(DataRow row in dTblResult.Rows)
                {
                    //Insert Task Alert
                    RecentTaskAlertNotify(row["AssignToLogin"].ToString(), (short)(Constant.TableType.Case), workflowModel.Workflow.CaseID, (int)(Constant.MessageType.New), string.Format(Constant.RecentActivity.TaskAlertForCase, strCaseRefNo),
                                          string.Format(Constant.RecentActivity.CaseURL, workflowModel.Workflow.CaseID), blnAlertIsRead, strLastUpdatedBy, workflowModel.Workflow.AssignByName, dtNow);
                    strAssignToEmail += row["AssignToEmail"].ToString() + ",";
                    //RecentTaskAlertNotify(workflowModel.Workflow.AssignTo.ID, (short)(Constant.TableType.Case), workflowModel.Workflow.CaseID, (int)(Constant.MessageType.New), string.Format(Constant.RecentActivity.TaskAlertForCase, strCaseRefNo),
                    //                  string.Format(Constant.RecentActivity.CaseURL, workflowModel.Workflow.CaseID), blnAlertIsRead, strLastUpdatedBy, workflowModel.Workflow.AssignByName, dtNow);

                }
            }

            #region Send Email Function
            if (assignedUser.Email != null)
            {
                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.BackOfficeReviewNotification, workflowModel.Workflow.CreatedBy, workflowModel.Workflow.CaseID, dtNow);
            }
            #endregion

            #region BackOffice for Assigned Unit - UTH  
            if (assignedUser.UnitTypeID == (int)Constant.UnitTypeID.UTH  && assignedUser.AssignToType==(int)Constant.WorkFlow.AssignToType.Unit) {
                svc.InsertBackOfficeQueueForCase(workflowModel.Workflow.CaseID);
            }
            #endregion

            return Json(data);

        }

      

        [HttpGet]
        [CRMAuthorize(Constant.Authentication.Cases.ViewCaseProfile)]
        public IHttpActionResult GetCurrentWorkFlowById(long id)
        {
            CasesWorkflowActionViewModel data = null;
            data = svc.GetCurrentWorkFlowById(id, userSvc.UserInfo);

            return Json(data);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.ViewCaseProfile)]
        public IHttpActionResult GetPagedCaseListByID(CaseListPagedListViewModel paging)
        {
            int intCount = 0;
            var lst = svc.GetCaseListByID(paging, out intCount);
            DTResultViewModel<CaseListViewModel> objRecord = null;

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


            return Json(objRecord);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetWorkFlowAssignToByKategoryId(WorkflowAssignToUnitIDViewModel Kategory)
        {
            WorkflowAssignToUnitIDViewModel data = null;
            data = workflowsvc.GetWorkFlowAssignToByKategoryId(Kategory);

            WorkflowUserViewModel assignedUser = new WorkflowUserViewModel();
            if (data != null)
            {
                if(data.ID == -1)
                {
                    assignedUser.DisplayName = data.DisplayName;
                    assignedUser.ID = data.ID.ToString();
                }
                else
                {
                    assignedUser.DisplayName = data.DisplayName;
                    assignedUser.ID = data.ID.ToString();
                    assignedUser.AssignToType = data.AssignToTypeID;
                    assignedUser.ManagerFunctionRoleID = data.ManagerFunctionRoleID;
                    assignedUser.UnitTypeID = data.UnitTypeID;
                }
          
            }
            else
            {
                assignedUser.DisplayName = "No default unit";
                assignedUser.ID = "-1";
            }

            return Json(assignedUser);
        }

        [HttpPost]
        public IHttpActionResult GetWorkFlowSearchUserOrUnit(WorkflowUserViewModel data)
        {
            var managerLoginId = userSvc.Manager != null ? userSvc.Manager.ID : null; //Get Manager LoginId
            data.ManagerId = managerLoginId != null ? managerLoginId : "";

            return Json(workflowsvc.GetWorkFlowAllUserOrUnit(data));
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetDashboardMyCreatedCase(CaseBelumSelesaiAssignToDashboardViewModel paging)
        {
            string strCreatedBy = userSvc.LoginID;
            int intCount = 0;
            var lst = svc.GetDashboardMyCreatedCase(strCreatedBy, paging, out intCount);

            DTResultViewModel<CaseBelumSelesaiAssignToDashboardViewModel> objRecord = null;

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

            return Json(objRecord);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetDashboardMyPendingCase(CaseBelumSelesaiAssignToDashboardViewModel paging)
        {
            string strCreatedBy = userSvc.LoginID;
            int intCount = 0;
            var lst = svc.GetDashboardMyPendingCase(strCreatedBy, paging, out intCount);

            DTResultViewModel<CaseBelumSelesaiAssignToDashboardViewModel> objRecord = null;

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

            return Json(objRecord);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetAssignCaseForUnit(CaseBelumSelesaiAssignToDashboardViewModel paging)
        {
            int intCount = 0;
            paging.UnitID = userSvc.UnitID;
            paging.UserLoginID = userSvc.UserInfo.LoginID;
            List<CaseBelumSelesaiAssignToDashboardViewModel> data = null;
            data = svc.GetDashboardAssignCaseForUnit(paging, out intCount);

            DTResultViewModel<CaseBelumSelesaiAssignToDashboardViewModel> objRecord = null;

            objRecord = new DTResultViewModel<CaseBelumSelesaiAssignToDashboardViewModel>()
            {
                recordsTotal = intCount,
                recordsFiltered = intCount,
                data = data
            };

            return Json(objRecord);
        }

        [HttpPost]
        public IHttpActionResult GetCaseBulkAssignListing(CaseAssignmentViewModel paging)
        {
            int intCount = 0;

            List<CaseAssignmentViewModel> data = null;
            paging.LoginID = userSvc.UserInfo.LoginID;
            List<WorkFlowIDs>  workflowList = new List<WorkFlowIDs>();
            data = svc.GetCaseBulkAssignListing(paging, out intCount, out workflowList);
            DTResultViewModel<CaseAssignmentViewModel> objRecord = null;
            
            objRecord = new DTResultViewModel<CaseAssignmentViewModel>()
            {
                recordsTotal = intCount,
                recordsFiltered = intCount,
                data = data,
                WorkflowList = workflowList
            };

            return Json(objRecord);
        }

        [HttpPost]
        public IHttpActionResult GetCaseReassignListing(CaseAssignmentViewModel paging)
        {
            int intCount = 0;

            List<CaseAssignmentViewModel> data = null;
            paging.LoginID = userSvc.UserInfo.LoginID;
            List<WorkFlowIDs> workflowList = new List<WorkFlowIDs>();
            data = svc.GetCaseReassignListing(paging, out intCount, out workflowList);
            DTResultViewModel<CaseAssignmentViewModel> objRecord = null;

            objRecord = new DTResultViewModel<CaseAssignmentViewModel>()
            {
                recordsTotal = intCount,
                recordsFiltered = intCount,
                data = data,
                WorkflowList = workflowList
            };

            return Json(objRecord);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        [CRMAuthorize(Constant.Authentication.Cases.PrintNotaTemuduga)]
        public IHttpActionResult PrintPenerimaanDoc(PrintPreviewViewModel model)
        {
            string strContent = svc.PrintPenerimaanDoc(model.CaseID, userSvc.DisplayName,userSvc.UserInfo.Unit.UnitName,model.QRCode,model.QRCodeDate,model.DocKategoryActID);

            return Json(strContent);
        }

        [HttpPost]
        [AllowAnonymous]
        public IHttpActionResult CreateCaseCFF(CaseUpdateViewModel model)
        {
            var data = CreateCase(model);
            return Json(data);
        }


        [HttpGet]
        public IHttpActionResult GetCaseReassignDropdown()
        {
            return Json(svc.GetCaseReassignDropdown());
        }

        [HttpPost]
        public IHttpActionResult ReassignBulkWorkflow(WorkflowUpdateViewModel model)
        {
            DateTime now = DateTime.Now;
            model.Workflow.AssignByName = userSvc.UserInfo.DisplayName;
            model.Workflow.AssignBy = userSvc.UserInfo.LoginID;
            model.Workflow.AssignByEmail = userSvc.UserInfo.Email;
            var data = workflowsvc.ReassignWorkflow(ref model, now);
            WorkflowUserViewModel assignedUser = model.Workflow.AssignTo;

            foreach (WorkflowActionViewModel reassignWF in model.WorkFlowList)
            {
                #region Send Email Function
                if (assignedUser.Email != null)
                {
                    String strAssignToEmail = assignedUser.Email;
                    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.BackOfficeReviewNotification, model.Workflow.CreatedBy, reassignWF.CaseID, now);
                }
                #endregion

                #region BackOffice for Assigned Unit - UTH  
                if (assignedUser.UnitTypeID == (int)Constant.UnitTypeID.UTH && assignedUser.AssignToType == (int)Constant.WorkFlow.AssignToType.Unit)
                {
                    svc.InsertBackOfficeQueueForCase(reassignWF.CaseID);
                }
                #endregion
            }
            return Json(data);
        }

        [HttpPost]
        [ValidateAjaxRequest]
        public IHttpActionResult GetCaseAssignDefaultUnitByUnitID(int UnitID)
        {
            WorkflowAssignToUnitIDViewModel data = null;
            data = workflowsvc.GetCaseAssignDefaultUnitByUnitID(UnitID);

            WorkflowUserViewModel assignedUser = new WorkflowUserViewModel();
            if (data != null)
            {
                if (data.ID == -1)
                {
                    assignedUser.DisplayName = data.DisplayName;
                    assignedUser.ID = data.ID.ToString();
                }
                else
                {
                    assignedUser.DisplayName = data.DisplayName;
                    assignedUser.ID = data.ID.ToString();
                    assignedUser.AssignToType = data.AssignToTypeID;
                    assignedUser.ManagerFunctionRoleID = data.ManagerFunctionRoleID;
                    assignedUser.UnitTypeID = data.UnitTypeID;
                }

            }
            else
            {
                assignedUser.DisplayName = "No default unit";
                assignedUser.ID = "-1";
            }

            return Json(assignedUser);
        }
    }
}