using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

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

namespace Fab2ApprovalSystem.Misc;

public class ECNHelper {

    private const string ECN_PREFIX = "ECN_";
    private const string TECN_PREFIX = "TECN_";
    private const string ETECN_PREFIX = "ETECN_";

    public static bool IsITAR(ECN ecn) {
        if (ecn.IsRH && !ecn.IsAU && !ecn.IsIndustrial && !ecn.IsMA) {
            return true;
        } else
            return false;
    }

    public static string NotifyEmergencyTECNApproval(AppSettings appSettings, int ecnNumber, DateTime? expDate, ECN ecn) {
        string emailSentList = "";
        string senderName = "E-TECN";
        string userEmail = string.Empty;
        string subject = "E-TECN Approved";
        string emailTemplate = "ETECNApproved.txt";
        List<string> emailIst = MiscDMO.GetEmergencyTECNApprovalNotifyList(ecnNumber).Distinct().ToList();
        string ecnFolderPath = appSettings.AttachmentFolder + "E-TECNZipped\\" + ETECN_PREFIX + ecnNumber.ToString() + ".zip";
        subject = "E-TECN Approved notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[5];
        emailparams[0] = ecnNumber.ToString();
        emailparams[1] = ecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = "E-TECN";
        emailparams[4] = expDate is null ? string.Empty : expDate.Value.ToString();

        if (IsITAR(ecn))
            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, emailparams);
        else
            en.SendNotificationEmailWithAttachment(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, ecnFolderPath, emailparams);

        emailSentList = string.Join(", ", emailIst.Distinct().ToArray());
        return emailSentList;
    }

    public static string NotifyApproversForCancellation(AppSettings appSettings, int ecnNumber, byte currentStep, int documentType, string ecnTypeString, ECN ecn) {
        string emailSentList = "";
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "TECNCancellationApproval.txt";
        List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList();
        string subject = ecnTypeString + " Cancellation Approval Required - " + ecnNumber + " for " + ecn.Title + ", Cancellation initiated on :" + ecn.CancellationDate;
        foreach (string email in emailIst) {
            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[4];
            emailparams[0] = ecnNumber.ToString();
            emailparams[1] = ecnNumber.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = ecnTypeString;
            userEmail = email;

            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
            emailSentList += email + ",";
        }

        return emailSentList;
    }

    public static string NotifyApproversForRecall(AppSettings appSettings, int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string recallComments, ECN ecn) {
        string emailSentList = "";

        List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList();
        emailIst.Add("Jeanne.McIntyre@infineon.com");
        emailIst.Add("Jonathan.Ouellette@infineon.com");
        string emailTemplate = "ECNRecallApproval.txt";
        string userEmail = string.Empty;
        string subject = ecnTypeString + " Recalled  - " + ecnNumber + " for " + ecn.Title + ", Recall initiated on :" + DateTime.Now.ToString();
        string senderName = ecnTypeString;

        foreach (string email in emailIst) {
            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[5];
            emailparams[0] = ecnNumber.ToString();
            emailparams[1] = ecnNumber.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = ecnTypeString;
            emailparams[4] = recallComments;
            userEmail = email;

            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
            emailSentList += email + ",";
        }

        return emailSentList;
    }

    public static string NotifyApproversForExpiration(AppSettings appSettings, int ecnNumber, byte currentStep, int documentType, string ecnTypeString, ECN ecn) {
        string emailSentList = "";
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "TECNExpirationApproval.txt";
        List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList();
        string subject = " TECN Expiration Approval Reqquired - " + ecnTypeString + "# " + ecnNumber + " for " + ecn.Title + ", Expired:" + ecn.ExpirationDate;

        foreach (string email in emailIst) {
            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[4];
            emailparams[0] = ecnNumber.ToString();
            emailparams[1] = ecnNumber.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = ecnTypeString;
            userEmail = email;
#if (DEBUG)
            userEmail = GlobalVars.SENDER_EMAIL;
#endif

            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
            emailSentList += email + ",";
        }

        return emailSentList;
    }

    public static string NotifyTECNCancellation(AppSettings appSettings, UserAccountDMO userDMO, int ecnNumber, string ecnFolderPath, string comments, ECN ecn, List<int> notificationUserList) {
        string emailSentList = "";
        List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList();
        foreach (int userId in notificationUserList) {
            string email = userDMO.GetUserEmailByID(userId);
            if (email != null && !emailIst.Contains(email))
                emailIst.Add(email);
        }

        string subject;
        string emailTemplate;
        string senderName = "ECN";
        string userEmail = string.Empty;
        DateTime dateTime = ecn.CancellationApprovalDate is null ? DateTime.Now : ecn.CancellationApprovalDate.Value;
        if (ecn.ExpirationDate > DateTime.Today || ecn.ExtensionDate > DateTime.Today) {
            emailTemplate = "TECNCancelled.txt";
            subject = "TECN Cancellation Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Cancelled:" + dateTime;
        } else {
            emailTemplate = "TECNReturnedToProcess.txt";
            subject = "TECN Return to Process Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Returned:" + dateTime;
        }

        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[6];
        emailparams[0] = ecnNumber.ToString();
        emailparams[1] = ecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = "TECN";
        emailparams[4] = DateTime.Now.ToString();
        emailparams[5] = comments;

#if (DEBUG)
        userEmail = GlobalVars.SENDER_EMAIL;
#endif

        if (IsITAR(ecn))
            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, emailparams);
        else
            en.SendNotificationEmailWithAttachment(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, ecnFolderPath, emailparams);
        emailSentList = string.Join(", ", emailIst.Distinct().ToArray());
        return emailSentList;
    }

    public static string NotifyTECNAutoCancellation(AppSettings appSettings, int ecnNumber, int tecnNumber, List<string> attachments, ECN ecn) {
        string emailSentList = "";
        string senderName = "ECN";
        string subject = string.Empty;
        string userEmail = string.Empty;
        string emailTemplate = "TECNAutoCancelled.txt";
        List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList();
        subject = "TECN Conversion and Cancellation Notice - " + tecnNumber + " for " + ecn.Title + ", Converted on:" + DateTime.Now;

        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[6];
        emailparams[0] = tecnNumber.ToString();
        emailparams[1] = tecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = "TECN";
        emailparams[4] = DateTime.Now.ToString();
        emailparams[5] = ecnNumber.ToString();

#if (DEBUG)
        userEmail = GlobalVars.SENDER_EMAIL;
#endif

        if (IsITAR(ecn))
            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, emailparams);
        else
            en.SendNotificationEmailWithAttachments(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, attachments, emailparams);
        emailSentList = string.Join(", ", emailIst.Distinct().ToArray());
        return emailSentList;
    }

    public static string NotifyTECNExpiration(AppSettings appSettings, int ecnNumber, string ecnFolderPath, ECN ecn) {
        string emailSentList = "";
        string senderName = "ECN";
        string userEmail = string.Empty;
        string emailTemplate = "TECNExpired.txt";
        List<string> emailIst = MiscDMO.GetEmergencyTECNApprovalNotifyList(ecnNumber).Distinct().ToList();
        string subject = "TECN Expiration Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Expired:" + ecn.ExpirationDate;

        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[5];
        emailparams[0] = ecnNumber.ToString();
        emailparams[1] = ecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = "TECN";
        emailparams[4] = ecn.ExpirationDate.Value.ToShortDateString();

        if (IsITAR(ecn))
            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, emailparams);
        else
            en.SendNotificationEmailWithAttachment(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, emailIst, null, subject, ecnFolderPath, emailparams);

        emailSentList = string.Join(", ", emailIst.Distinct().ToArray());
        return emailSentList;
    }

    public static void ReAssignApproval(AppSettings appSettings, int issueID, string ecnTypeString, string email, ECN ecn) {
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNReAssigned.txt";
        string subject = ecnTypeString + " Re-Assignment";

        subject = ecnTypeString + " Re-Assignment" + " - Email would be sent to " + email + " for Number " + ecn.ECNNumber + ", - " + ecn.Title;
        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[4];
        emailparams[0] = issueID.ToString();
        emailparams[1] = issueID.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = ecnTypeString;
        userEmail = email;

        en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
    }

    public static string AddEECNApproval(AppSettings appSettings, int ecnNumber, string emailSentList, string emailArray, ECN ecn) {
        string senderName = "E-TECN";
        string userEmail = string.Empty;
        string subject = "E-TECN Assignment";
        string emailTemplate = "ECNAssigned.txt";
        string[] emailIst = emailArray.Split(new char[] { '~' });
        foreach (string email in emailIst) {
            if (email.Length > 0) {
                subject = "E-TECN Assignment notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
                EmailNotification en = new(appSettings, subject);
                string[] emailparams = new string[4];
                emailparams[0] = ecnNumber.ToString();
                emailparams[1] = ecnNumber.ToString();
                emailparams[2] = GlobalVars.hostURL;
                emailparams[3] = "E-TECN";

                userEmail = email;

                en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
                emailSentList += email + ",";

            }

        }

        return emailSentList;
    }

    public static string AddAdditionalApproval(AppSettings appSettings, int issueID, string ecnTypeString, string emailSentList, string emailArray, ECN ecn) {
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNAssigned.txt";
        string subject = ecnTypeString + " Assignment";
        string[] emailIst = emailArray.Split(new char[] { '~' });
        foreach (string email in emailIst) {
            if (email.Length > 0) {
                subject = ecnTypeString + "Assignment notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
                EmailNotification en = new(appSettings, subject);
                string[] emailparams = new string[4];
                emailparams[0] = issueID.ToString();
                emailparams[1] = issueID.ToString();
                emailparams[2] = GlobalVars.hostURL;
                emailparams[3] = ecnTypeString;

                userEmail = email;
                en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
                emailSentList += email + ",";

            }

        }

        return emailSentList;
    }

    public static void ReAssignApproverByAdmin(AppSettings appSettings, int issueID, string ecnTypeString, string email, ECN ecn) {
        string subject;
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNReAssigned.txt";

        subject = ecnTypeString + " Re-Assignment" + " - ECN #" + ecn.ECNNumber + ", - " + ecn.Title;
        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[4];
        emailparams[0] = issueID.ToString();
        emailparams[1] = issueID.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = ecnTypeString;

        userEmail = email;

        en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
    }

    public static string NotifyTECNExtensionRejectionToOrginator(AppSettings appSettings, int issueID, string ecnTypeString, List<string> emailIst, ECN ecn, string username) {
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string subject = ecnTypeString + " Rejection";
        string emailTemplate = "TECNExtensionReject.txt";

        foreach (string email in emailIst) {
            subject = ecnTypeString + " Extension Rejection notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[5];
            emailparams[0] = issueID.ToString();
            emailparams[1] = issueID.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = username;
            emailparams[4] = ecnTypeString;
            userEmail = email;

            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
        }

        return userEmail;
    }

    public static string NotifyRejectionToOrginator(AppSettings appSettings, int issueID, string ecnTypeString, string comments, List<string> emailIst, ECN ecn, string username) {
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNReject.txt";
        string subject = ecnTypeString + " Rejection";

        foreach (string email in emailIst) {
            subject = ecnTypeString + " Rejection notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[6];
            emailparams[0] = issueID.ToString();
            emailparams[1] = issueID.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = username;
            emailparams[4] = ecnTypeString;
            emailparams[5] = comments;
            userEmail = email;
            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
        }

        return userEmail;
    }

    public static string NotifyApprovers(AppSettings appSettings, int ecnNumber, string ecnTypeString, string emailSentList, ECN ecn, List<string> emailIst) {
        string subject = string.Empty;
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNAssigned.txt";

        subject = ecnTypeString + " Assignment notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;
        foreach (string email in emailIst) {

            EmailNotification en = new(appSettings, subject);
            string[] emailparams = new string[4];
            emailparams[0] = ecnNumber.ToString();
            emailparams[1] = ecnNumber.ToString();
            emailparams[2] = GlobalVars.hostURL;
            emailparams[3] = ecnTypeString;
            userEmail = email;

            en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
            emailSentList += email + ",";
        }

        return emailSentList;
    }

    public static string NotifyAdmin(AppSettings appSettings, int ecnNumber, string ecnTypeString, ECN ecn, int id) {
        string emailSentList;
        string subject = string.Empty;
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        string emailTemplate = "ECNApproved.txt";
        string ecnCreatedByEmail = MiscDMO.GetEmail(id);

        subject = ecnTypeString + " Approval notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;

        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[4];
        emailparams[0] = ecnNumber.ToString();
        emailparams[1] = ecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = ecnTypeString;
        userEmail = ecnCreatedByEmail;

        en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
        emailSentList = ecnCreatedByEmail;
        return emailSentList;
    }

    public static string NotifySubmitter(AppSettings appSettings, int ecnNumber, string ecnTypeString, ECN ecn) {
        string emailSentList;
        string subject = string.Empty;
        string userEmail = string.Empty;
        string senderName = ecnTypeString;
        int ecnCreatedById = ecn.OriginatorID;
        string emailTemplate = "ECNApproved.txt";
        string ecnCreatedByEmail = MiscDMO.GetEmail(ecnCreatedById);

        subject = ecnTypeString + " Approval notice for Number " + ecn.ECNNumber + ", - " + ecn.Title;

        EmailNotification en = new(appSettings, subject);
        string[] emailparams = new string[4];
        emailparams[0] = ecnNumber.ToString();
        emailparams[1] = ecnNumber.ToString();
        emailparams[2] = GlobalVars.hostURL;
        emailparams[3] = ecnTypeString;
        userEmail = ecnCreatedByEmail;

        en.SendNotificationEmail(emailTemplate, GlobalVars.SENDER_EMAIL, senderName, userEmail, null, subject, emailparams);
        emailSentList = ecnCreatedByEmail;
        return emailSentList;
    }

    public static bool CreateZip(AppSettings appSettings, ECNPdf ecn, string UserId) {
        try {
            string sourceDirectory = appSettings.AttachmentFolder + "ECN\\" + ecn.ECNNumber.ToString() + "\\";
            string outputFullFilePath = "";

            string outputFileName;
            if (ecn.IsTECN) {
                if (ecn.ExtensionDate != null)
                    outputFileName = TECN_PREFIX + ecn.ECNNumber.ToString() + "_Extension.zip";
                else
                    outputFileName = TECN_PREFIX + ecn.ECNNumber.ToString() + ".zip";

                outputFullFilePath = appSettings.AttachmentFolder + "\\ECNZipped\\" + outputFileName;
            } else if (ecn.IsEmergencyTECN) // Transfer it to different folder , coz documentum does not need to have a Workflow Item created for Emergency TECN
              {
                outputFileName = ETECN_PREFIX + ecn.ECNNumber.ToString() + ".zip";
                outputFullFilePath = appSettings.AttachmentFolder + "\\E-TECNZipped\\" + outputFileName;
            } else {
                outputFileName = ECN_PREFIX + ecn.ECNNumber.ToString() + ".zip";
                outputFullFilePath = appSettings.AttachmentFolder + "\\ECNZipped\\" + outputFileName;
            }

            Zipper zip = new();
            zip.CreateZip(outputFullFilePath, sourceDirectory);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecn.ECNNumber, UserID = UserId, DocumentType = ecn.IsECN ? "ECN" : (ecn.IsEmergencyTECN ? "E-TECN" : "TECN"), OperationType = "Error", Comments = ex.Message });
            return false;
        }

        return true;
    }

    public static string AddEECNApproval(AppSettings appSettings, string userId, WorkflowDMO wfDMO, int ecnNumber, out byte step, string engUserIDs, string OpUserIDs, ECN ecn) {
        string emailSentList = "";
        step = 1;
        string emailArray = "";
        try {
            emailArray = wfDMO.AddEECNApproval(ecnNumber, step, (int)GlobalVars.DocumentType.EECN, engUserIDs, OpUserIDs);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " Step:" + step + " " + " Userid:" + engUserIDs + " - " + OpUserIDs + " - " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(appSettings, userId + "\r\n AddEECNApproval\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = userId, DocumentType = "E-TECN ", OperationType = "Error", Comments = "AddEECNApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
        emailSentList = AddEECNApproval(appSettings, ecnNumber, emailSentList, emailArray, ecn);
        return emailSentList;
    }

    public static string AttachSave(AppSettings appSettings, ECN_DMO ecnDMO, int ecnNumber, string returnString, int userId, string fullFileName, Stream stream) {
        // Some browsers send file names with full path.
        // We are only interested in the file name.
        var fileName = Path.GetFileName(fullFileName);

        string ecnFolderPath = appSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString();

        DirectoryInfo di = new(ecnFolderPath);
        if (!di.Exists)
            try {
                di.Create();
            } catch {
                returnString = "Error creating ECN directory.";
            }
        if (returnString == "") {
            var physicalPath = Path.Combine(ecnFolderPath, fileName);
            if (!File.Exists(physicalPath)) {
                using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) {
                    stream.CopyTo(fileStream);
                }
                ECNAttachment attach = new() {
                    ECNNumber = ecnNumber,
                    FileName = fileName,
                    UserID = userId,
                };
                if (File.Exists(physicalPath)) {
                    ecnDMO.InsertECNAttachment(attach);
                } else {
                    returnString = "File was not uploaded to server.";
                }
            } else {
                returnString = "Cannot have duplicate file names.";
            }
        }

        return returnString;
    }

}