#pragma warning disable CS8019

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Mail;

#pragma warning restore CS8019

namespace Fab2ApprovalSystem.Misc;

public class EmailNotification {

    #region Variabls
    protected string _subject = null;
    protected string _TemplatesPath = null;
    private readonly Models.AppSettings _AppSettings;
    #endregion

    public EmailNotification(Models.AppSettings appSettings) =>
       _AppSettings = appSettings;

    public EmailNotification(Models.AppSettings appSettings, string EmailHeaderSubject) {
        _AppSettings = appSettings;
        _subject = EmailHeaderSubject;
        _TemplatesPath = appSettings.EmailTemplatesPath;
    }

    /// <summary>
    /// The Constructor Function
    /// </summary>
    /// <param name="EmailHeaderSubject">Email Header Subject</param>
    /// <param name="TemplatesPath">Emails Files Templates</param>
    public EmailNotification(Models.AppSettings appSettings, string EmailHeaderSubject, string TemplatesPath) {
        _AppSettings = appSettings;
        _subject = EmailHeaderSubject;
        _TemplatesPath = TemplatesPath;
    }

    public EmailNotification(Models.AppSettings appSettings, string subject, string templatesPath, string emailSubject) :
        this(appSettings, subject, templatesPath) =>
            EmailSubject = emailSubject;

    /// <summary>
    /// Email subject
    /// </summary>
    public string EmailSubject {
        set => _subject = value;
    }

    /// <summary>
    /// This function will read the content of a file name
    /// </summary>
    /// <param name="FileName">File Name</param>
    /// <returns>String: Containing the Entire content of the file</returns>
    protected string ReadEmailFile(string FileName) {
        string retVal = null;
        try {
            string path = _TemplatesPath + FileName;
#if !NET8
            FileInfo TheFile = new FileInfo(System.Web.HttpContext.Current.Server.MapPath(path));

            // check if the file exists in the location.
            if (!TheFile.Exists)
                throw new Exception("Could Not Find the file : " + FileName + " in the location " + _TemplatesPath); // throw an exception here.

            // start reading the file. i have used Encoding 1256 to support arabic text also.
            StreamReader sr = new StreamReader(System.Web.HttpContext.Current.Server.MapPath(@path), System.Text.Encoding.GetEncoding(1256));
            retVal = sr.ReadToEnd(); // getting the entire text from the file.
            sr.Close();
#endif
        } catch (Exception ex) {
            throw new Exception("Error Reading File." + ex.Message);
        }
        return retVal;
    }

    /// <summary>
    /// this function will send email. it will read the mail setting from the web.config
    /// </summary>
    /// <param name="SenderEmail">Sender Email ID</param>
    /// <param name="SenderName">Sender Name</param>
    /// <param name="Recep">Recepient Email ID</param>
    /// <param name="cc">CC ids</param>
    /// <param name="email_title">Email Subject</param>
    /// <param name="email_body">Email Body</param>
#pragma warning disable IDE0060 // Remove unused parameter
    protected void SendEmail(string SenderEmail, string SenderName, string Recep, string cc, string email_title, string email_body) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress("MesaFabApproval@infineon.com", "Mesa Fab Approval");
        msg.Sender = new MailAddress("MesaFabApproval@infineon.com", "Mesa Fab Approval");
        // adding the Recepient Email ID
        msg.To.Add(Recep);
        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new("mailrelay-internal.infineon.com");

        // sending the message.
        try {
            SmtpMail.Send(msg);
        } catch (Exception ex) {
            Console.WriteLine("Exception caught in CreateTestMessage2(): {0}",
                ex.ToString());
        }
    }
#pragma warning restore IDE0060 // Remove unused parameter

    protected void SendEmailWithAttachment(string SenderEmail, string SenderName, string Recep, string cc, string email_title, string email_body, string attachmentPath) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress(SenderEmail, SenderName);

        // adding the Recepient Email ID
        msg.To.Add(Recep);

        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;
        msg.Attachments.Add(new Attachment(attachmentPath));

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new();
#if(!DEBUG)
        // sending the message.
        SmtpMail.Send(msg);
#endif
    }

#pragma warning disable IDE0060 // Remove unused parameter
    protected void SendEmail(string SenderEmail, string SenderName, List<string> RecepientList, string cc, string email_title, string email_body) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress("MesaFabApproval@infineon.com", "Mesa Fab Approval");
        // adding the Recepient Email ID
        foreach (string recepient in RecepientList) {
            msg.To.Add(recepient);
        }

        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new();

        // sending the message.
        try {
            SmtpMail.Send(msg);
        } catch (Exception ex) {
            Console.WriteLine("Exception caught in CreateTestMessage2(): {0}",
                ex.ToString());
        }
    }
#pragma warning restore IDE0060 // Remove unused parameter

    protected void SendEmailWithAttachment(string SenderEmail, string SenderName, List<string> RecepientList, string cc, string email_title, string email_body, string attachmentPath) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress(SenderEmail, SenderName);

        // adding the Recepient Email ID
        foreach (string recepient in RecepientList) {
            if (recepient != null)
                msg.To.Add(recepient);
        }

        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;
        msg.Attachments.Add(new Attachment(attachmentPath));

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new();

        // sending the message.
        SmtpMail.Send(msg);
    }

    protected void SendEmailWithAttachments(string SenderEmail, string SenderName, string Recep, string cc, string email_title, string email_body, List<string> attachments) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress(SenderEmail, SenderName);

        // adding the Recepient Email ID
        msg.To.Add(Recep);

        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;
        foreach (string attachment in attachments) {
            msg.Attachments.Add(new Attachment(attachment));
        }

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new();
#if(!DEBUG)
        // sending the message.
        SmtpMail.Send(msg);
#endif
    }

    protected void SendEmailWithAttachments(string SenderEmail, string SenderName, List<string> RecepientList, string cc, string email_title, string email_body, List<string> attachments) {
        // creating email message
        MailMessage msg = new();
        msg.IsBodyHtml = true;// email body will allow html elements

        // setting the Sender Email ID
        msg.From = new MailAddress(SenderEmail, SenderName);

        // adding the Recepient Email ID
        foreach (string recepient in RecepientList) {
            if (recepient != null)
                msg.To.Add(recepient);
        }

        // add CC email ids if supplied.
        if (!string.IsNullOrEmpty(cc))
            msg.CC.Add(cc);

        // setting email subject and body
        msg.Subject = email_title;
        msg.Body = email_body;

        foreach (string attachment in attachments) {
            msg.Attachments.Add(new Attachment(attachment));
        }

        // create a Smtp Mail which will automatically get the smtp server details from web.config mailSettings section
        SmtpClient SmtpMail = new();

        // sending the message.
        SmtpMail.Send(msg);
    }

    /// <summary>
    /// This function will send the email notification by reading the email template and substitute the arguments
    /// </summary>
    /// <param name="EmailTemplateFile">Email Template File</param>
    /// <param name="SenderEmail">Sender Email</param>
    /// <param name="SenderName">Sender Name</param>
    /// <param name="RecepientEmail">Recepient Email ID</param>
    /// <param name="CC">CC IDs</param>
    /// <param name="Subject">EMail Subject</param>
    /// <param name="Args">Arguments</param>
    /// <returns>String: Return the body of the email to be send</returns>
    public string SendNotificationEmail(string EmailTemplateFile, string SenderEmail, string SenderName, string RecepientEmail, string CC, string Subject, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                SendEmail(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? Subject + " for: " + RecepientEmail : _subject), retVal);
            } else {
#if(!DEBUG)
                SendEmail(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject  : _subject), retVal);
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    /// <summary>
    /// This function will send the email notification by reading the email template and substitute the arguments along with the attachments
    /// </summary>

    public string SendNotificationEmailWithAttachment(string EmailTemplateFile, string SenderEmail, string SenderName, string RecepientEmail, string CC, string Subject, string attachmentPath, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                SendEmailWithAttachment(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? " TESTING ONLY -IGNORE : " + Subject + RecepientEmail : _subject), retVal, attachmentPath);
            } else {
#if(!DEBUG)
                SendEmailWithAttachment(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal, attachmentPath);
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    public string SendNotificationEmailWithAttachment(string EmailTemplateFile, string SenderEmail, string SenderName, List<string> RecepientEmail, string CC, string Subject, string attachmentPath, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                foreach (string email in RecepientEmail) {
                    Subject += email + ";";
                }

                RecepientEmail.Clear();
                SendEmailWithAttachment(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? " TESTING ONLY -IGNORE : " + Subject : _subject), retVal, attachmentPath);
            } else {
#if (!DEBUG)
                SendEmailWithAttachment(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal, attachmentPath);                    
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    public string SendNotificationEmailWithAttachments(string EmailTemplateFile, string SenderEmail, string SenderName, string RecepientEmail, string CC, string Subject, List<string> attachments, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                SendEmailWithAttachments(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? " TESTING ONLY -IGNORE : " + Subject + RecepientEmail : _subject), retVal, attachments);
            } else {
#if(!DEBUG)
                SendEmailWithAttachments(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal, attachments);
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    public string SendNotificationEmailWithAttachments(string EmailTemplateFile, string SenderEmail, string SenderName, List<string> RecepientEmail, string CC, string Subject, List<string> attachments, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                foreach (string email in RecepientEmail) {
                    Subject += email + ";";
                }

                RecepientEmail.Clear();
                SendEmailWithAttachments(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? " TESTING ONLY -IGNORE : " + Subject : _subject), retVal, attachments);
            } else {
#if (!DEBUG)
                SendEmailWithAttachments(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal, attachments);                    
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    public string SendNotificationEmail(string EmailTemplateFile, string SenderEmail, string SenderName, List<string> RecepientEmail, string CC, string Subject, params string[] Args) {
        string retVal = null;

        // reading the file
        string FileContents = ReadEmailFile(EmailTemplateFile);

        string emailBody = FileContents;

        // setting formatting the string
        retVal = string.Format(emailBody, Args);

        try {
            // check if we are in debug mode or not. to send email
            if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
                foreach (string email in RecepientEmail) {
                    Subject += email + ";";
                }
                RecepientEmail.Clear();
                SendEmail(SenderEmail, SenderName, GetTestRecipientsList(), CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal);
            } else {
#if (!DEBUG)
                    SendEmail(SenderEmail, SenderName, RecepientEmail, CC, (!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal);
#endif
            }
        } catch (Exception ex) {
            throw;
        }

        return retVal;
    }

    public void SendNotificationEmailToAdmin(string subject, string body, MailPriority importance) {
        try {
            SmtpClient client = new(_AppSettings.SMTPServer);
            MailMessage msg = new();

            string toList = _AppSettings.AdminNotificationRecepient;
            msg.From = new MailAddress(_AppSettings.NotificationSender);

            string[] recipients = toList.Split(',');
            foreach (string recipient in recipients)
                msg.To.Add(new MailAddress(recipient.Trim()));

            DateTime now = DateTime.Now;

            string temp = now.ToString() + " - " + body;
            msg.Subject = subject;
            msg.Body = temp;
            msg.Priority = importance;
            client.Send(msg);
        } catch (Exception ex) {
            throw;
        }
    }

    public List<string> GetTestRecipientsList() {
        List<string> r = new();
        try {
            string emails = _AppSettings.TestEmailRecipients;
            foreach (string s in emails.Split(';', ',')) {
                if (!string.IsNullOrWhiteSpace(s))
                    r.Add(s);
            }
        } catch {
            r.Add("dhuang2@infineon.com");
        }
        return r;
    }
}