using System;
using System.Collections.Generic;
using System.Linq;
#if !NET8
using System.Web;
using System.Web.Mvc;
using System.Web.Services;
#endif

#if NET8
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
#endif

using Fab2ApprovalSystem.DMO;
using Fab2ApprovalSystem.Misc;
using Fab2ApprovalSystem.Models;
using Fab2ApprovalSystem.ViewModels;

#if !NET8
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
#endif

namespace Fab2ApprovalSystem.Controllers;

[Authorize]
#if !NET8
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[SessionExpireFilter]
#endif
#if NET8
[Route("[controller]")]
#endif
public class ChangeControlController : Controller {

    private readonly ChangeControlDMO ccDMO = new();
    private readonly AppSettings? _AppSettings = GlobalVars.AppSettings;

    public ActionResult Index() {
        return View();
    }

    public ActionResult Create() {
        ChangeControlViewModel cc = new();
        try {
            cc.OwnerID = GlobalVars.GetUserId(GetSession());
            ccDMO.InsertChangeControl(cc);
            return RedirectToAction("Edit", new { issueID = cc.PlanNumber });
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + cc.PlanNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n Create - Change Control\r\n" + cc.PlanNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = cc.PlanNumber, UserID = GetUserIdentityName(), DocumentType = "Change Control", OperationType = "Error", Comments = "Create - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult Edit(int issueID) {
        string jwt = GlobalVars.GetJWT(GetSession());
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
        string refreshToken = GlobalVars.GetRefreshToken(GetSession());
        string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
        string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}";

        return Redirect(mrbUrl);
    }

    public ActionResult ReadOnlyCC(int issueID) {
        string jwt = GlobalVars.GetJWT(GetSession());
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
        string refreshToken = GlobalVars.GetRefreshToken(GetSession());
        string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
        string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}";

        return Redirect(mrbUrl);
    }

    [HttpPost]
    public ActionResult Edit(ChangeControlViewModel model) {
        try {
            var data = model;
            ccDMO.UpdateChangeControl(model, GlobalVars.GetUserId(GetSession()));
            ViewBag.AIResponsibles = ccDMO.GetActionItemResponsible();
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content("Successfully Saved");
    }

    public int GetUserIDByDisplayName(string displayName) {
        try {
            var UserList = ccDMO.GetUsers();

            int UserID = (from a in UserList where a.AttendeeName.Equals(displayName) select a.AttendeeID).First();

            return UserID;
        } catch (Exception ex) {
            return 0;
        }
    }

    public JsonResult SearchParts(string searchText) {
        List<string> partList = MiscDMO.SearchLTParts(searchText.Trim()).Select(x => x.WIPPartData).ToList();
        return GetJsonResult(partList);
    }

#if !NET8

    public ActionResult GetCCAttachments([DataSourceRequest] DataSourceRequest request, int planNumber) {
        return Json(ccDMO.GetCCAttachment(planNumber).ToDataSourceResult(request));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateCCAttachment([DataSourceRequest] DataSourceRequest request, CCAttachment model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.UpdateCCAttachemnt(model);
        }

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteCCAttachment([DataSourceRequest] DataSourceRequest request, CCAttachment model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeleteCCAttachemnt(model);
        }

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    public ActionResult InsertCCAttachmentItem([DataSourceRequest] DataSourceRequest request, CCAttachment model) {
        if (model != null && ModelState.IsValid) {
            model = ccDMO.InsertCCAttachment(model);
        }

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    public ActionResult AttachSaveCC(IEnumerable<HttpPostedFileBase> files, int planNumber, int attachID) {
        // The Name of the Upload component is "files"
        if (files != null) {
            int userId = GlobalVars.GetUserId(GetSession());
            foreach (var file in files) {
                ChangeControlHelper.AttachSaveCC(_AppSettings, ccDMO, planNumber, attachID, userId, file.FileName, file.InputStream);
            }
        }
        return Content("");
    }

    public ActionResult GetMeetingDecisionSummaryList([DataSourceRequest] DataSourceRequest request, int planNumber) {
        return Json(ccDMO.GetMeetingDecisionSummaryList(planNumber).ToDataSourceResult(request));
    }

    public ActionResult GetMeetingAttachments([DataSourceRequest] DataSourceRequest request, int meetingID) {
        return Json(ccDMO.GetMeetingAttachments(meetingID).ToDataSourceResult(request));
    }

    public ActionResult GetPCRB([DataSourceRequest] DataSourceRequest request, int PlanNumber, string PCRB) {
        return Json(ccDMO.GetPCRB(PlanNumber, PCRB).ToDataSourceResult(request));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateMeetingAttachmentAttrib([DataSourceRequest] DataSourceRequest request, CCMeetingAttachment model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.UpdateMeetingAttachmentAttrib(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteMeetingAttachment([DataSourceRequest] DataSourceRequest request, CCMeetingAttachment model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeleteMeetingAttachemnt(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult InsertMeetingAttachmentItemAttrib([DataSourceRequest] DataSourceRequest request, CCMeetingAttachment model) {
        if (model != null && ModelState.IsValid) {
            model = ccDMO.InsertMeetingAttachmentAttrib(model);
        }

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    public ActionResult AttachSaveMeeting(IEnumerable<HttpPostedFileBase> files, int planNumber, int meetingID, int attachID) {
        // The Name of the Upload component is "files"
        if (files != null) {
            int userId = GlobalVars.GetUserId(GetSession());
            foreach (var file in files) {
                ChangeControlHelper.AttachSaveMeeting(_AppSettings, ccDMO, planNumber, attachID, userId, file.FileName, file.InputStream);
            }
        }
        return Content("");
    }

#endif

    public FileResult DownloadCCFile(string fileGuid, int planNumber) {
        string fileName = ccDMO.GetCCFileName(fileGuid);

        string fileExtension = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));

        string ecnFolderPath = _AppSettings.AttachmentFolder + "ChangeControl\\" + planNumber.ToString();
        var sDocument = System.IO.Path.Combine(ecnFolderPath, fileGuid + fileExtension);

        var FDir_AppData = _AppSettings.AttachmentFolder;
        if (!sDocument.StartsWith(FDir_AppData)) {
            // Ensure that we are serving file only inside the Fab2ApprovalAttachments folder
            // and block requests outside like "../web.config"
            throw new HttpException(403, "Forbidden");
        }

        if (!System.IO.File.Exists(sDocument)) {
            return null;
        }

        return File(sDocument, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    }

    public ActionResult CreateMeeting(int planNumber) {
        try {
            int meetingID = ccDMO.InsertMeeting(planNumber);
            return Content(meetingID.ToString());
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + planNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n Create - Meeting\r\n" + planNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = planNumber, UserID = GetUserIdentityName(), DocumentType = "Meeting", OperationType = "Error", Comments = "Create - " + exceptionString });
            throw new Exception("Error: " + e.Message);
        }
    }

    public ActionResult EditMeeting(int meetingID) {
        int isITARCompliant = 1;
        CCMeeting meeting = new();
        meeting = ccDMO.GetMeetingRead(meetingID, out isITARCompliant, GlobalVars.GetUserId(GetSession()));
        ViewBag.MeetingList = ccDMO.GetMeetingList(meeting.PlanNumber);
        // TODO locked functionality
        List<ApproversListViewModel> userList = MiscDMO.GetApproversListByDocument(meeting.PlanNumber, meeting.CurrentStep, (int)GlobalVars.DocumentType.ChangeControl);
        ApproversListViewModel appUser = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == GlobalVars.GetUserId(GetSession()); });
        if (appUser != null) {
            ViewBag.IsApprover = "true";
        }

        if (isITARCompliant == 0) // not ITAR Compliant
        {
            return View("UnAuthorizedAccess");
        } else {
            if ((meeting.RecordLockIndicator && meeting.RecordLockedBy != GlobalVars.GetUserId(GetSession()))
                || (meeting.PCRBClosed)) {
                return RedirectToAction("ReadOnlyMeeting", new { meetingID = meetingID });
            } else if (meeting.Decision != -1) {
                return RedirectToAction("EditMeetingUpdate", new { meetingID = meetingID });
            } else {
                ViewBag.AIResponsibles = ccDMO.GetActionItemResponsible();
                ViewBag.Attendees = ccDMO.GetUsers();
                ViewBag.Sites = ccDMO.GetSites();
                ViewBag.PCRValues = ccDMO.GetPCRValues();
                meeting = ccDMO.GetMeeting(meetingID, out isITARCompliant, GlobalVars.GetUserId(GetSession()));

                return View(meeting);
            }
        }
    }

    public ActionResult ReadOnlyMeeting(int meetingID) {
        int isITARCompliant = 1;
        CCMeeting meeting = new();
        meeting = ccDMO.GetMeetingRead(meetingID, out isITARCompliant, GlobalVars.GetUserId(GetSession()));
        ViewBag.MeetingList = ccDMO.GetMeetingList(meeting.PlanNumber);
        ViewBag.PCRValues = ccDMO.GetPCRValues();

        if (isITARCompliant == 0) // not ITAR Compliant
        {
            return View("UnAuthorizedAccess");
        } else {
            return View(meeting);
        }
    }

    [HttpPost]
    public ActionResult EditMeeting(CCMeeting meeting) {
        try {
            ccDMO.UpdateMeeting(meeting);
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content("Successfully Saved");
    }

    public ActionResult EditMeetingUpdate(int meetingID) {
        int isITARCompliant = 1;
        CCMeeting meeting = new();
        meeting = ccDMO.GetMeetingRead(meetingID, out isITARCompliant, GlobalVars.GetUserId(GetSession()));
        ViewBag.MeetingList = ccDMO.GetMeetingList(meeting.PlanNumber);
        ViewBag.PCRValues = ccDMO.GetPCRValues();
        // TODO locked functionality
        List<ApproversListViewModel> userList = MiscDMO.GetApproversListByDocument(meeting.PlanNumber, meeting.CurrentStep, (int)GlobalVars.DocumentType.ChangeControl);
        ApproversListViewModel appUser = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == GlobalVars.GetUserId(GetSession()); });
        if (appUser != null) {
            ViewBag.IsApprover = "true";
        }

        if (isITARCompliant == 0) // not ITAR Compliant
        {
            return View("UnAuthorizedAccess");
        } else {
            if ((meeting.RecordLockIndicator && meeting.RecordLockedBy != GlobalVars.GetUserId(GetSession()))
                || (meeting.PCRBClosed)) {
                return RedirectToAction("ReadOnlyMeeting", new { meetingID = meetingID });
            } else {
                meeting = ccDMO.GetMeeting(meetingID, out isITARCompliant, GlobalVars.GetUserId(GetSession()));

                ViewBag.AIResponsibles = ccDMO.GetActionItemResponsible();

                return View(meeting);
            }
        }
    }

    public FileResult DownloadMeetingFile(string fileGuid, int planNumber) {
        string fileName = ccDMO.GetMeetingFileName(fileGuid);

        string fileExtension = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));

        string ecnFolderPath = _AppSettings.AttachmentFolder + "ChangeControl\\" + planNumber.ToString();
        var sDocument = System.IO.Path.Combine(ecnFolderPath, fileGuid + fileExtension);

        var FDir_AppData = _AppSettings.AttachmentFolder;
        if (!sDocument.StartsWith(FDir_AppData)) {
            // Ensure that we are serving file only inside the Fab2ApprovalAttachments folder
            // and block requests outside like "../web.config"
            throw new HttpException(403, "Forbidden");
        }

        if (!System.IO.File.Exists(sDocument)) {
            return null;
        }

        return File(sDocument, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    }

#if !NET8

    public ActionResult GetDecisionsSummaryList([DataSourceRequest] DataSourceRequest request, int meetingID) {
        return Json(ccDMO.GetDecisionsSummaryList(meetingID).ToDataSourceResult(request));
    }

#endif

    public ActionResult UpdateMeetingDecisionNotes(CCDecisionSummary model) {
        try {
            ccDMO.UpdateDecisionSummary(model);
        } catch (Exception ex) {
            return Content(ex.Message);
        }
        return Content("Saved Succesfully");
    }

#if !NET8

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteDecisionsSummary([DataSourceRequest] DataSourceRequest request, CCDecisionSummary model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeleteDecisionSummary(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

#endif

    public ActionResult InsertDecisionsSummary(CCDecisionSummary model) {
        try {
            ccDMO.InsertDecisionSummary(model);
        } catch (Exception ex) {
            return Content(ex.Message);
        }
        return Content("Saved Succesfully");
    }

    public ActionResult UpdateECN_LotDispoLinks(int id, string ecnLinks, string lotDispoLinks) {
        try {
            ccDMO.UpdateDecisionSummaryLinks(id, ecnLinks, lotDispoLinks);
        } catch (Exception ex) {
            return Content(ex.Message);
        }
        return Content("Saved Succesfully", "application/json");
    }

#if !NET8

    public ActionResult GetMeetingList([DataSourceRequest] DataSourceRequest request, int planNumber) {
        var meetingList = ccDMO.GetMeetingList(planNumber);
        return Json(meetingList.ToDataSourceResult(request));
    }

    public ActionResult GetMeetingAttendees([DataSourceRequest] DataSourceRequest request, int meetingID) {
        return Json(ccDMO.GetMeetingAttendees(meetingID).ToDataSourceResult(request));
    }

    public ActionResult GetPCRBAttendees([DataSourceRequest] DataSourceRequest request, int PCRBID) {
        return Json(ccDMO.GetPCRBAttendees(PCRBID).ToDataSourceResult(request));
    }

#endif

    public void InsertNewMeetingAttendee(string attendeeName, string jobTitle, string siteName) {
        try {
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
        }
    }

    public void UpdateMeetingAttendee(int id, string attendeeName, string jobTitle, string siteName) {
        int docid = id;
        try {
            ccDMO.UpdateMeetingAttendee(id, attendeeName, jobTitle, siteName);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + docid.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n UpdateMeetingAttendee - Change Control\r\n" + docid.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = docid, UserID = GetUserIdentityName(), DocumentType = "Change Control", OperationType = "Error", Comments = "UpdateMeetingAttendee - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    [HttpPost]
    public void UpdatePCRBAttendee(int id, int attendeeId, string jobTitle, string siteName) {
        int docid = id;

        try {
            ccDMO.UpdatePCRBAttendee(id, attendeeId, jobTitle, siteName);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + docid.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n UpdateMeetingAttendee - Change Control\r\n" + docid.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = docid, UserID = GetUserIdentityName(), DocumentType = "Change Control", OperationType = "Error", Comments = "UpdateMeetingAttendee - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

#if !NET8

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteMeetingAttendee([DataSourceRequest] DataSourceRequest request, CCMeetingAttendee model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeleteMeetingAttendee(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult InsertMeetingAttendee([DataSourceRequest] DataSourceRequest request, int pcrId, int attendeeId, string jobTitle, string siteName) {
        CCPCRBAttendee newAttendee = new CCPCRBAttendee();
        newAttendee.AttendeeID = attendeeId;
        newAttendee.PCRBID = pcrId;
        newAttendee.JobTitle = jobTitle;
        newAttendee.Location = siteName;

        try {
            ccDMO.InsertMeetingAttendee(newAttendee);
        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

    public ActionResult GetMeetingActionItems([DataSourceRequest] DataSourceRequest request, int meetingID) {
        return Json(ccDMO.GetMeetingActionItems(meetingID).ToDataSourceResult(request));
    }

    public ActionResult GetPCRBActionItems([DataSourceRequest] DataSourceRequest request, int pcrbID) {
        return Json(ccDMO.GetPCRBActionItems(pcrbID).ToDataSourceResult(request));
    }

    public ActionResult GetMeetingActionItems_All([DataSourceRequest] DataSourceRequest request, int planNumber) {
        return Json(ccDMO.GetMeetingActionItems_All(planNumber).ToDataSourceResult(request));
    }

#endif

    public ActionResult InsertPCRBActionItem(CCPCRBActionItem model) {
        try {
            if (model != null) {
                ccDMO.InsertPCRBActionItem(model);
            }

        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

    public ActionResult InsertMeetingActionItem(CCMeetingActionItem model) {
        try {
            if (model != null) {
                ccDMO.InsertMeetingActionItem(model);
            }

        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

#if !NET8

    public ActionResult InsertPCRBAttendee([DataSourceRequest] DataSourceRequest request, int pcrId, int attendeeId, string jobTitle, string siteName) {
        CCPCRBAttendee newAttendee = new CCPCRBAttendee();
        newAttendee.AttendeeID = attendeeId;
        newAttendee.PCRBID = pcrId;
        newAttendee.JobTitle = jobTitle;
        newAttendee.Location = siteName;

        try {
            ccDMO.InsertPCRBAttendee(newAttendee);
        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

#endif

    public ActionResult UpdatePCRBActionItem(CCPCRBActionItem model) {
        try {
            if (model != null) {
                ccDMO.UpdatePCRBActionItem(model);
            }
        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

#if !NET8

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateMeetingActionItemAll([DataSourceRequest] DataSourceRequest request, CCMeetingActionItemAll model) {
        if (model != null && ModelState.IsValid) {
            model.ClosedBy = GlobalVars.GetUserId(GetSession());
            ccDMO.UpdateMeetingActionItem_All(model);
        }
        if (model.ClosedStatus)
            model.ClosedDate = DateTime.Now;
        else
            model.ClosedDate = null;

        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

#endif

    public ActionResult UpdateMeetingActionItem(CCMeetingActionItem model) {
        try {
            if (model != null) {
                ccDMO.UpdateMeetingActionItem(model);
            }
        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

    [HttpPost]
    public ActionResult ReassignMeetingActionItemResponsiblePersons(int meetingActionItemId, string newResponsiblePersonIDs, string comments) {
        if (GlobalVars.IsAdminValueNull(GetSession()))
            throw new Exception("Permission denied");

        try {
            ccDMO.ReassignMeetingActionItemResponsiblePersons(meetingActionItemId, newResponsiblePersonIDs, comments, GlobalVars.GetUserId(GetSession()));
        } catch (Exception ex) {
            return Content(ex.Message.ToString());
        }

        return Content("1");
    }

#if !NET8

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteMeetingActionItem([DataSourceRequest] DataSourceRequest request, CCMeetingActionItem model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeleteMeetingActionItem(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

    public ActionResult DeletePCRBActionItem([DataSourceRequest] DataSourceRequest request, CCPCRBActionItem model) {
        if (model != null && ModelState.IsValid) {
            ccDMO.DeletePCRBActionItem(model);
        }
        return Json(new[] { model }.ToDataSourceResult(request, ModelState));
    }

#endif

    public void CompleteCC(int planNumber) {
        int docid = planNumber;
        try {
            ccDMO.CompleteCC(planNumber);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + docid.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n CompleteCC - Change Control\r\n" + docid.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = docid, UserID = GetUserIdentityName(), DocumentType = "Change Control", OperationType = "Error", Comments = "CompleteCC - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void CancelCC(int planNumber) {
        int docid = planNumber;
        try {
            ccDMO.CancelCC(planNumber);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + docid.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n CompleteCC - Change Control\r\n" + docid.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = docid, UserID = GetUserIdentityName(), DocumentType = "Change Control", OperationType = "Error", Comments = "CancelCC - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

#if !NET8

    public ActionResult AttachSaveActionItem(IEnumerable<HttpPostedFileBase> AIfiles, int planNumber, int attachID) {
        // The Name of the Upload component is "files"
        if (AIfiles != null) {
            int userId = GlobalVars.GetUserId(GetSession());
            foreach (var file in AIfiles) {
                ChangeControlHelper.AttachSaveActionItem(_AppSettings, ccDMO, planNumber, attachID, userId, file.FileName, file.InputStream);
            }
        }
        return Content("");
    }

#endif

    public FileResult DownloadActionItemFile(string fileGuid, int planNumber) {
        string fileName = ccDMO.GetActionItemFileName(fileGuid);

        string fileExtension = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));

        string ecnFolderPath = _AppSettings.AttachmentFolder + "ChangeControl\\" + planNumber.ToString();
        var sDocument = System.IO.Path.Combine(ecnFolderPath, fileGuid + fileExtension);

        var FDir_AppData = _AppSettings.AttachmentFolder;
        if (!sDocument.StartsWith(FDir_AppData)) {
            // Ensure that we are serving file only inside the Fab2ApprovalAttachments folder
            // and block requests outside like "../web.config"
            throw new HttpException(403, "Forbidden");
        }

        if (!System.IO.File.Exists(sDocument)) {
            return null;
        }

        return File(sDocument, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    }

    public void UpdateMeetingNotes(int meetingID, string notes) {
        ccDMO.UpdateMeetingNotes(meetingID, notes);
    }

    public void ReleaseLockOnDocument(int planNumber) {
        ccDMO.ReleaseLockOnDocument(GlobalVars.GetUserId(GetSession()), planNumber);

        try {
            ccDMO.ReleaseLockOnDocument(GlobalVars.GetUserId(GetSession()), planNumber);
        } catch (Exception e) {
            try {
                Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n ReleaseLockOnDocument LD\r\n" + planNumber.ToString() + "\r\n" + e.Message, System.Diagnostics.EventLogEntryType.Error);
            } catch { }
            ccDMO.ReleaseLockOnDocument(-1, planNumber);
        }
    }

    public JsonResult GetAllUsersList() {
        UserAccountDMO userDMO = new();
        IEnumerable<LoginModel> userlist = userDMO.GetAllUsers();
        return GetJsonResult(userlist);
    }

    [HttpPost]
    public void ReAssignOwnerByAdmin(string planNumber, string comments, int newOwnerId) {
        if (GlobalVars.IsAdminValueNull(GetSession()))
            throw new Exception("Permission denied");

        int planNumberInt = 0;

        try {
            // remove non-numeric characters from Plan # then convert to int
            planNumberInt = int.Parse(new string(planNumber.Where(char.IsNumber).ToArray()));

            ccDMO.ReassignOwner(planNumberInt, newOwnerId, comments, GlobalVars.GetUserId(GetSession()));
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim();
            if (exceptionString.Length > 450)
                exceptionString = exceptionString.Substring(0, 450);
            Functions.WriteEvent(_AppSettings, GetUserIdentityName() + "\r\n ReAssignOwnerByAdmin\r\n" + planNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = planNumberInt, UserID = GetUserIdentityName(), DocumentType = "ChangeControl", OperationType = "Error", Comments = "ReAssignOwnerByAdmin - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult GetPCRBMesaTitle(int issueID) {
        int isItarCompliant = 1;
        ChangeControlViewModel cc = ccDMO.GetChangeControlRead(issueID, out isItarCompliant, GlobalVars.GetUserId(GetSession()));
        string content = cc.PlanTitle;
        return Content(content);
    }

#if !NET8

    private System.Web.HttpSessionStateBase GetSession() =>
        Session;

    private JsonResult GetJsonResult(object? data) =>
        Json(data, JsonRequestBehavior.AllowGet);

    private bool IsAjaxRequest() =>
        Request.IsAjaxRequest();

#endif

#if NET8

    private Microsoft.AspNetCore.Http.ISession GetSession() =>
        HttpContext.Session;

    private JsonResult GetJsonResult(object? data) =>
        Json(data);

    private bool IsAjaxRequest() =>
        Request.Headers.TryGetValue("X-Requested-With", out Microsoft.Extensions.Primitives.StringValues strings) && strings[0] == "XMLHttpRequest";

#endif

    private string GetUserIdentityName() =>
        @User.Identity.Name;

}