using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Fab2ApprovalSystem.Models;
using Fab2ApprovalSystem.DMO;
using Fab2ApprovalSystem.Misc;
using System.IO;
using System.Configuration;
using Fab2ApprovalSystem.Utilities;

namespace Fab2ApprovalSystem.Controllers
{
    [Authorize]
    [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
    [SessionExpireFilter]
    public class AuditController : Controller
    {
        AuditDMO auditDMO = new AuditDMO();
        UserUtilities adUsers = new UserUtilities();
        // GET: Audit
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ActionResult Create()
        {


            Audit audit = new Audit();
            try
            {
                // TODO: Add insert logic here


                audit.OriginatorID = (int)Session[GlobalVars.SESSION_USERID];
                auditDMO.InsertAudit(audit);
                return RedirectToAction("Edit", new { issueID = audit.AuditNo });
            }
            catch (Exception e)
            {
                string detailedException = "";
                try
                {
                    detailedException = e.InnerException.ToString();
                }
                catch
                {
                    detailedException = e.Message;
                }
                string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + audit.AuditNo.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                Functions.WriteEvent(@User.Identity.Name + "\r\n SubmitDocument - Audit\r\n" + audit.AuditNo.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                EventLogDMO.Add(new WinEventLog() { IssueID = audit.AuditNo, UserID = @User.Identity.Name, DocumentType = "Audit", OperationType = "Error", Comments = "SubmitDocument - " + exceptionString });
                throw new Exception(e.Message);

            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="issueID"></param>
        /// <returns></returns>
        public ActionResult Edit(int issueID)
        {
            int isITARCompliant = 1;
            Audit audit = new Audit();

            try
            {
                List<int> userList = auditDMO.Get8DQA();
                ViewBag.MesaUsers = adUsers.GetMesaUsers();
                int QAs = userList.Find(delegate(int al) { return al == (int)Session[GlobalVars.SESSION_USERID]; });
                ViewBag.Is8DQA = "false";
                if (QAs != 0)
                {
                    ViewBag.Is8DQA = "true";
                }

                audit = auditDMO.GetAuditItem(issueID, (int)Session[GlobalVars.SESSION_USERID]);
                //transform audit users from string to list, delimited by a comma.
                if(audit.Auditees == null || !audit.Auditees.Contains(","))
                {
                    ViewBag.AuditeeNames = audit.Auditees;
                }
                else
                {
                    string[] auditeeNames = audit.Auditees.Split(',');
                    ViewBag.AuditeeNames = auditeeNames.ToList();
                    
                }
                


                ViewBag.IsSubmitter = false;
                if(audit.OriginatorID == (int)Session[GlobalVars.SESSION_USERID])
                {
                    ViewBag.IsSubmitter = true;
                }
                if((bool)Session[GlobalVars.IS_ADMIN] != true)
                {
                    ViewBag.IsAdmin = false;
                }
                else
                {
                    ViewBag.IsAdmin = true;
                }
                if ((audit.RecordLockIndicator && audit.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) 
                    || audit.AuditStatus != 0 ) //open
                {
                    return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo });
                }
                if (ViewBag.IsAdmin == false && ViewBag.IsSubmitter == false)
                {
                    return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo });
                }
                else
                {
                    ViewBag.UserList = auditDMO.GetUserList();
                    ViewBag.AuditTypeList = auditDMO.GetAuditTypeList();
                    //ViewBag.AuditStandardList = auditDMO.GetAuditStandardList();
                    ViewBag.AuditorList = auditDMO.GetAuditorList();
                    ViewBag.AuditAreaList = auditDMO.GetAuditAreaList();
                    ViewBag.AuditFindingCategoryList = auditDMO.GetAuditFindingCategories();
                    ViewBag.CANoList = auditDMO.GetCorrectiveActionNoList();
                }
             

            }
            catch (Exception e)
            {
                string detailedException = "";
                try
                {
                    detailedException = e.InnerException.ToString();
                }
                catch
                {
                    detailedException = e.Message;
                }
                string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + audit.AuditNo.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                Functions.WriteEvent(@User.Identity.Name + "\r\n Edit - Audit\r\n" + audit.AuditNo.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                EventLogDMO.Add(new WinEventLog() { IssueID = audit.AuditNo, UserID = @User.Identity.Name, DocumentType = "Audit", OperationType = "Error", Comments = "Edit - " + exceptionString });
                throw new Exception(e.Message);

            }


            return View(audit);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Edit(Audit model)
        {
            try
            {

                var data = model;
                auditDMO.UpdateAudit(model, (int)Session[GlobalVars.SESSION_USERID]);
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }

            return Content("Successfully Saved");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public ActionResult CheckCAStatus(int auditNo)
        {
            int dataCount = -1;
            try
            {
                dataCount = auditDMO.GetOpenCACountByAuditNo(auditNo);
            }
            catch (Exception ex)
            {
                throw;
            }

            return Content(dataCount.ToString());

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public ActionResult ReadOnlyAudit(int auditNo)
        {
            Audit audit = new Audit();
            audit = auditDMO.GetAuditItemReadOnly(auditNo, (int)Session[GlobalVars.SESSION_USERID]);
          
            ViewBag.AuditTypeList = auditDMO.GetAuditTypeList();
            ViewBag.AuditorList = auditDMO.GetAuditorList();
            ViewBag.AuditAreaList = auditDMO.GetAuditAreaList();
            ViewBag.AuditFindingCategoryList = auditDMO.GetAuditFindingCategories();


            return View(audit);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="AuditReportFiles"></param>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public ActionResult AuditReportAttachSave(IEnumerable<HttpPostedFileBase> AuditReportFiles, int auditNo)
        {
            try
            {
                // The Name of the Upload component is "files"
                if (AuditReportFiles != null)
                {
                    foreach (var file in AuditReportFiles)
                    {
                        // Some browsers send file names with full path.
                        // We are only interested in the file name.


                        var fileName = Path.GetFileName(file.FileName);
                        var fileExtension = Path.GetExtension(file.FileName);
                        //var physicalPath = Path.Combine(Server.MapPath("~/UserUploads"), fileName);       
                        DirectoryInfo di;
                        var ccPhysicalPath = Functions.GetAttachmentFolder() + @"Audit\" + auditNo;
                        di = new DirectoryInfo(ccPhysicalPath);
                        if (!di.Exists)
                            di.Create();


                        var guid = Guid.NewGuid().ToString();
                        var physicalPath = Path.Combine(Functions.GetAttachmentFolder() + @"Audit\" + auditNo + @"\", guid + fileExtension);


                        file.SaveAs(physicalPath);
                        AuditReportAttachment attach = new AuditReportAttachment()
                        {
                            AuditNo = auditNo,
                            FileGUID = guid,
                            FileName = fileName,
                            UploadedByID = (int)Session[GlobalVars.SESSION_USERID]

                        };


                        //ccDMO.InsertCCAttachment(attach);
                        auditDMO.InsertAuditReportAttachment(attach);
                    }
                }
            }
            catch
            {
                throw;
            }


            return Content("");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public ActionResult AuditReportAttachment_Read([DataSourceRequest] DataSourceRequest request, int auditNo)
        {
            
            return Json(auditDMO.GetAuditReportAttachments(auditNo).ToDataSourceResult(request));
        }

        

        /// <summary>
        /// 
        /// </summary>
        /// <param name="attachID"></param>
        [HttpPost]
        public void DeleteAuditReportAttachment(int attachID)
        {
            auditDMO.DeleteAuditReportAttachment(attachID);

            
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileGuid"></param>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public FileResult DownloadAuditReportAttachment(string fileGuid, int auditNo)
        {
            try
            {
                string fileName = auditDMO.GetAuditReportAttachmentFileName(fileGuid);

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

                string ecnFolderPath = Functions.GetAttachmentFolder() + "Audit\\" + auditNo.ToString();
                var sDocument = Path.Combine(ecnFolderPath, fileGuid + fileExtension);

                var FDir_AppData = Functions.GetAttachmentFolder();
                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;
                    //throw new Exception("File not found");
                }

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

            catch
            {
                // TODO - proces the error
                throw;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="auditNo"></param>
        /// <returns></returns>
        public ActionResult GetAuditFindingsList([DataSourceRequest] DataSourceRequest request, int auditNo)
        {

            return Json(auditDMO.GetAuditFindingsList(auditNo).ToDataSourceResult(request));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public ActionResult InsertAuditFindingsItem(AuditFindings data)
        {
            Audit audit = new Audit();
            auditDMO.InsertAuditFindingsItem(data);
            audit = auditDMO.GetAuditItem(data.AuditNo, (int)Session[GlobalVars.SESSION_USERID]);

            return Json(audit, JsonRequestBehavior.AllowGet);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public ActionResult UpdateAuditFindingsItem(AuditFindings data)
        {
            Audit audit = new Audit();
            auditDMO.UpdateAuditFindingsItem(data);
            audit = auditDMO.GetAuditItem(data.AuditNo, (int)Session[GlobalVars.SESSION_USERID]);

            return Json(audit, JsonRequestBehavior.AllowGet);
        }


        public ActionResult DeleteAuditFindingsItem(int auditFindingsID)
        {
            var af = auditDMO.GetAuditFindingsByID(auditFindingsID);
            auditDMO.DeleteAuditFindingsItem(auditFindingsID);
            var audit = auditDMO.GetAuditItem(af.AuditNo, (int)Session[GlobalVars.SESSION_USERID]);
            return Json(audit, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="issueID"></param>
        public void ReleaseLockOnDocument(int issueID)
        {
            try
            {
                auditDMO.ReleaseLockOnDocument((int)Session[GlobalVars.SESSION_USERID], issueID);
            }
            catch (Exception e)
            {
                try
                {
                    Functions.WriteEvent(@User.Identity.Name + "\r\n ReleaseLockOnDocument CA\r\n" + issueID.ToString() + "\r\n" + e.Message, System.Diagnostics.EventLogEntryType.Error);
                }
                catch { }
                auditDMO.ReleaseLockOnDocument(-1, issueID);

            }


        }


        // CA Findings ======================================================================================================================

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public ActionResult InsertCAFindingsItem(CAFindings data)
        {
            auditDMO.InsertCAFindings(data);
            if (data.ResponsibilityOwnerID != null)
            {
                // send an email notification
                NotifyActionItemOwner(data.AuditNo, data.ECD, data.ResponsibilityOwnerID);
            }
            
            return Content("");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public ActionResult UpdateCAFindingsItem(CAFindings data)
        {
            auditDMO.UpdateCAFindings(data);
            if (data.ResponsibilityOwnerID != data.CurrentResponsibilityOwnerID)
            {
                NotifyActionItemOwner(data.AuditNo, data.ECD, data.ResponsibilityOwnerID);
            }
            
            return Content("");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="caNo"></param>
        /// <returns></returns>
        public ActionResult GetCAFindingsList([DataSourceRequest] DataSourceRequest request, int auditNo)
        {

            return Json(auditDMO.GetCAFindingsList(auditNo).ToDataSourceResult(request));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="d7PAID"></param>
        /// <returns></returns>
        public ActionResult GetCAFindingsItemAttachments([DataSourceRequest] DataSourceRequest request, int caFindingsID)
        {

            return Json(auditDMO.GetCAFindingsItemAttachments(caFindingsID).ToDataSourceResult(request));
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="d7paID"></param>
        /// <returns></returns>
        public ActionResult GetCAFindingsItem(int caFindingsID)
        {
            var model = new CAFindings();
            model = auditDMO.GetCAFindingsItem(caFindingsID);

            return PartialView("_CAFindingsAttachment", model);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="caFindingsID"></param>
        [HttpPost]
        public void DeleteCAFindingsItem(int caFindingsID)
        {
            auditDMO.DeleteCAFindingsItem(caFindingsID);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="D7PA_Attachemnt"></param>
        /// <param name="d7PAID"></param>
        /// <param name="caNo"></param>
        /// <returns></returns>
        public ActionResult SaveCAFindings_Attachemnt(IEnumerable<HttpPostedFileBase> CAFindings_Attachemnt, int caFindingsID, int auditNo)
        {
            try
            {
                // The Name of the Upload component is "files"
                if (CAFindings_Attachemnt != null)
                {
                    foreach (var file in CAFindings_Attachemnt)
                    {
                        // Some browsers send file names with full path.
                        // We are only interested in the file name.


                        var fileName = Path.GetFileName(file.FileName);
                        var fileExtension = Path.GetExtension(file.FileName);
                        //var physicalPath = Path.Combine(Server.MapPath("~/UserUploads"), fileName);       
                        DirectoryInfo di;
                        var ccPhysicalPath = Functions.GetAttachmentFolder() + @"Audit\" + auditNo;
                        di = new DirectoryInfo(ccPhysicalPath);
                        if (!di.Exists)
                            di.Create();


                        var guid = Guid.NewGuid().ToString();
                        var physicalPath = Path.Combine(Functions.GetAttachmentFolder() + @"Audit\" + auditNo + @"\", guid + fileExtension);


                        file.SaveAs(physicalPath);
                        AuditReportAttachment attach = new AuditReportAttachment()
                        {
                            CAFindingsID = caFindingsID,
                            AuditNo = auditNo,
                            FileGUID = guid,
                            FileName = fileName,
                            UploadedByID = (int)Session[GlobalVars.SESSION_USERID]

                        };


                        auditDMO.InsertAuditReportAttachment(attach);
                    }
                }
            }
            catch
            {
                throw;
            }


            return Content("");
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="issueID"></param>
        /// <param name="currentStep"></param>
        public void NotifyActionItemOwner(int issueID, DateTime? dueDate, int? responsibleOwnerID)
        {
            try
            {
                string emailSentList = "";

                //List<string> emailIst = ldDMO.GetApproverEmailList(@issueID, currentStep).Distinct().ToList();
                string email = MiscDMO.GetEmail(responsibleOwnerID);

                string emailTemplate = "CorrectiveActionFindingAssigned.txt";
                string userEmail = string.Empty;
                string subject = "5s/CA Findings";
                string senderName = "CorrectiveAction";

                EmailNotification en = new EmailNotification(subject, ConfigurationManager.AppSettings["EmailTemplatesPath"]);
                string[] emailparams = new string[5];
                emailparams[0] = Functions.ReturnAuditNoStringFormat(issueID);
                emailparams[1] = dueDate.ToString();
                emailparams[2] = Functions.DocumentTypeMapper(GlobalVars.DocumentType.Audit);
                emailparams[3] = GlobalVars.hostURL;
                emailparams[4] = issueID.ToString();
                userEmail = email;
                
                en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
                emailSentList += email + ",";

                try
                {

                    EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "Corrective Action", OperationType = "Email", Comments = "Task Assigned for 5S/CA Findings" + ":" + email });
                }
                catch { }
            }
            catch (Exception e)
            {
                string detailedException = "";
                try
                {
                    detailedException = e.InnerException.ToString();
                }
                catch
                {
                    detailedException = e.Message;
                }

                string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + " 5s/CAFindings:" + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                Functions.WriteEvent(@User.Identity.Name + "\r\n 5s/CAFindings - NotifyActionItemOwner\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "Corrective Action", OperationType = "Error", Comments = "5s/CAFindings Notification - " + exceptionString });
                //throw e;


            }

        }
        public ActionResult IsCAAssignedToAudit(int caNo, int auditNo)
        {            
            return Content(auditDMO.IsCAAssignedToAudit(caNo, auditNo).ToString());
        }


    }
}