using System.Globalization;
using System.Text;
using MailKit.Net.Smtp;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Report;
using Microsoft.Extensions.Options;
using MimeKit;


namespace MarcoBMS.Services.Service
{
    public class EmailSender : IEmailSender
    {
        private readonly SmtpSettings _smtpSettings;
        private readonly IConfiguration _configuration;
        private readonly IWebHostEnvironment _env;

        public EmailSender(IOptions<SmtpSettings> emailSettings, IConfiguration configuration, IWebHostEnvironment env)
        {
            _smtpSettings = emailSettings.Value;
            _configuration = configuration;
            _env = env;
        }

        public async Task<string> GetEmailTemplate(string templateName, Dictionary<string, string> replacements)
        {
            string path = Path.Combine(_env.ContentRootPath, "EmailTemplates", $"{templateName}.html");

            if (!File.Exists(path))
                throw new FileNotFoundException("Template file not found");

            string content = await File.ReadAllTextAsync(path);

            foreach (var item in replacements)
            {
                content = content.Replace($"{{{{{item.Key}}}}}", item.Value);
            }

            return content;
        }
        //public async Task<string> GetEmailTemplate1()
        //{
        //    string path = Path.Combine(_env.ContentRootPath, "EmailTemplates", $"send-otp.html");

        //    if (!File.Exists(path))
        //        throw new FileNotFoundException("Template file not found");

        //    string content = await File.ReadAllTextAsync(path);

        //    return content;
        //}

        public async Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink)
        {
            var replacements = new Dictionary<string, string>
            {
                { "MAIL_TITLE", "New registration,Reset Your Password" },
                { "RESET_PWD_URL", resetLink },
                { "RECEIVER_NAME", toName }
            };

            List<string> toEmails = new List<string>
            {
                toEmail
            };
            string emailBody = await GetEmailTemplate("new-user-email", replacements);

            await SendEmailAsync(toEmails, "New user registration, Reset Your Password", emailBody);
        }
        public async Task SendResetPasswordEmail(string toEmail, string userName, string resetLink)
        {
            var replacements = new Dictionary<string, string>
            {
                { "MAIL_TITLE", "Reset Your Password" },
                { "RESET_PWD_URL", resetLink }
            };

            string emailBody = await GetEmailTemplate("forgot-password", replacements);

            List<string> toEmails = new List<string>
            {
                toEmail
            };

            await SendEmailAsync(toEmails, "Reset Your Password", emailBody);

        }
        public async Task SendResetPasswordSuccessEmail(string toEmail, string toName)
        {
            var replacements = new Dictionary<string, string>
            {
                { "MAIL_TITLE", "Reset Password Successful" },
                { "RECEIVER_NAME", toName }
            };

            string emailBody = await GetEmailTemplate("password-change-success", replacements);

            List<string> toEmails = new List<string>
            {
                toEmail
            };
            await SendEmailAsync(toEmails, "Password Changed Successfully", emailBody);

        }
        public async Task SendRequestDemoEmail(List<string> toEmails, InquiryEmailObject demoEmailObject)
        {

            var replacements = new Dictionary<string, string>
            {
                { "MAIL_TITLE", "User Requested a Demo" },
                { "ORGANIZATION_NAME", demoEmailObject.OrganizatioinName ?? string.Empty },
                { "EMAIL", demoEmailObject.Email ?? string.Empty},
                { "ABOUT", demoEmailObject.About ?? string.Empty },
                { "ORGANIZATION_SIZE", demoEmailObject.OragnizationSize ?? string.Empty },
                { "INDUSTRY_NAME", demoEmailObject.IndustryName ?? string.Empty },
                { "CONTACT_NAME", demoEmailObject.ContactPerson ?? string.Empty },
                { "CONTACT_NUMBER", demoEmailObject.ContactNumber ?? string.Empty }
            };
            string emailBody = await GetEmailTemplate("request-demo", replacements);

            await SendEmailAsync(toEmails, "User Requested a Demo", emailBody);

        }
        public async Task<string> SendProjectStatisticsEmail(List<string> toEmails, string emailBody, string subject, ProjectStatisticReport report)
        {
            var date = report.Date.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture);
            var replacements = new Dictionary<string, string>
            {
                {"DATE", date},
                {"PROJECT_NAME", report.ProjectName},
                {"TIMESTAMP", report.TimeStamp},
                {"TODAYS_ATTENDANCES", report.TodaysAttendances.ToString("N0")},
                {"TOTAL_EMPLOYEES", report.TotalEmployees.ToString("N0")},
                {"TODAYS_PLANNED", report.TotalPlannedTask.ToString("N0")},
                {"TODAYS_COMPLETED", report.TotalCompletedTask.ToString("N0")},
                {"REGULARIZATION_PENDING", report.RegularizationPending.ToString("N0")},
                {"CHECKOUT_PENDING", report.CheckoutPending.ToString("N0")},
                {"TOTAL_PLANNED", report.TotalPlannedWork.ToString("N0")},
                {"TOTAL_COMPLETED", report.TotalCompletedWork.ToString("N0")},
                {"PROJECT_STATUS", report.CompletionStatus.ToString("P")},
                {"TODAYS_ASSIGNED", report.TodaysAssignTasks.ToString("N0")},
                {"REPORT_PENDING", report.ReportPending.ToString("N0")}
            };

            foreach (var item in replacements)
            {
                emailBody = emailBody.Replace($"{{{{{item.Key}}}}}", item.Value);
            }

            emailBody = emailBody.Replace("{{TEAM_ON_SITE}}", BuildTeamOnSiteHtml(report.TeamOnSite));
            emailBody = emailBody.Replace("{{PERFORMED_TASK}}", BuildPerformedTaskHtml(report.PerformedTasks, report.Date));
            emailBody = emailBody.Replace("{{PERFORMED_ATTENDANCE}}", BuildPerformedAttendanceHtml(report.PerformedAttendance));
            if (!string.IsNullOrWhiteSpace(subject))
            {
                var subjectReplacements = new Dictionary<string, string>
                {
                    {"DATE", date },
                    {"PROJECT_NAME", report.ProjectName}
                };
                foreach (var item in subjectReplacements)
                {
                    subject = subject.Replace($"{{{{{item.Key}}}}}", item.Value);
                }
                string env = _configuration["environment:Title"] ?? string.Empty;
                subject = CheckSubject(subject);
            }
            if (toEmails.Count > 0)
            {
                await SendEmailAsync(toEmails, subject, emailBody);
            }
            return emailBody;
        }
        public async Task SendOTP(List<string> toEmails, string emailBody, string name, string otp, string subject)
        {
            var replacements = new Dictionary<string, string>
            {
                { "NAME", name },
                { "OTP", otp }
            };

            foreach (var item in replacements)
            {
                emailBody = emailBody.Replace($"{{{{{item.Key}}}}}", item.Value);
            }

            subject = CheckSubject(subject);
            await SendEmailAsync(toEmails, subject, emailBody);
        }
        public async Task SendEmailAsync(List<string> toEmails, string subject, string body)
        {
            var email = new MimeMessage();
            email.From.Add(new MailboxAddress(_smtpSettings.SenderName, _smtpSettings.SenderEmail));
            foreach (var toEmail in toEmails)
            {
                email.To.Add(MailboxAddress.Parse(toEmail));
            }
            email.Subject = subject;

            var bodyBuilder = new BodyBuilder { HtmlBody = body };
            email.Body = bodyBuilder.ToMessageBody();

            using var smtp = new SmtpClient();
            await smtp.ConnectAsync(_smtpSettings.SmtpServer, _smtpSettings.Port, MailKit.Security.SecureSocketOptions.StartTls);
            await smtp.AuthenticateAsync(_smtpSettings.SenderEmail, _smtpSettings.Password);
            await smtp.SendAsync(email);
            await smtp.DisconnectAsync(true);
        }

        private string CheckSubject(string subject)
        {
            string env = _configuration["Environment:Title"] ?? string.Empty;
            if (string.IsNullOrWhiteSpace(env))
            {
                return subject = $"{subject}";
            }
            else
            {
                return subject = $"({env}) {subject}";
            }
        }
        private string BuildTeamOnSiteHtml(List<TeamOnSite> team)
        {
            if (team == null || !team.Any()) return "";

            var sb = new StringBuilder();
            sb.Append("<tr style=\"vertical-align:middle\">");

            int count = 0;
            foreach (var member in team)
            {
                if (count == 6)
                {
                    sb.Append("</tr><tr style=\"vertical-align:middle\">");
                    count = 0;
                }

                sb.AppendFormat(
                    "<td class=\"team\" style=\"text-align:center\">" +
                    "<div style=\"border: 1px solid #d5d5d5; border-radius: 10px; margin: 10px; padding: 10px;\">" +
                    "<div style=\"font-size: 15px; color: #525b75\">{0}</div>" +
                    "<div style=\"font-size: 20px; color: #003cc7; margin: 20px !important; font-weight: bold;\">{1}</div>" +
                    "</div></td>", member.RoleName, member.NumberofEmployees);

                count++;
            }

            sb.Append("</tr>");
            return sb.ToString();
        }
        private string BuildPerformedTaskHtml(List<PerformedTask> tasks, DateTime reportDate)
        {
            if (tasks == null || !tasks.Any())
            {
                return "<tr><td style=\"padding: 10px 0px 5px;\" colspan=\"6\">" +
                       "<span style=\"line-height: 25.2px; color: #666666;margin:10px\">" +
                       "No Activities (Tasks) Performed Today</span></td></tr>";
            }

            var sb = new StringBuilder();
            foreach (var task in tasks)
            {
                sb.AppendFormat("<tr>" +
                                "<td style=\"text-align:left;\"><span style=\"padding-left: 10px;\">{0}</span><br />" +
                                "<span style=\"color: gray; font-size: small; padding-left: 10px;\">{1}</span></td>" +
                                "<td style=\"text-align:center\">{2} / {3}</td>" +
                                "<td style=\"text-align:center\">{4}</td>" +
                                "<td style=\"text-align:center\">{5}</td>" +
                                "<td style=\"padding-left: 10px; text-align: left;\">",
                    task.Activity, task.Location, task.AssignedToday, task.Pending, task.CompletedToday, reportDate.ToString("dd-MMM-yyyy"));

                foreach (var member in task.Team)
                {
                    sb.AppendFormat("{0} <span style=\"color: gray; font-size: small; padding-left: 10px;\">({1})</span><br />",
                        member.Name, member.RoleName);
                }

                sb.AppendFormat("</td><td style=\"padding-left: 10px; max-width: 150px; text-align: left;\">{0}</td></tr>", task.Comment);
            }

            return sb.ToString();
        }
        private string BuildPerformedAttendanceHtml(List<PerformedAttendance> attendances)
        {
            if (attendances == null || !attendances.Any())
            {
                return "<tr><td style=\"padding: 10px 0px 5px;\" colspan=\"5\">" +
                       "<span style=\"line-height: 25.2px; color: #666666;margin:10px\">No Attendance Performed Today</span></td></tr>";
            }

            var sb = new StringBuilder();
            foreach (var a in attendances)
            {
                sb.AppendFormat("<tr>" +
                                "<td style=\"text-align:left\"><span style=\"padding-left:10px;\">{0}</span></td>" +
                                "<td style=\"text-align:center\">{1}</td>" +
                                "<td style=\"text-align:center\">{2}</td>" +
                                "<td style=\"text-align:center\">{3}</td>" +
                                "<td style=\"padding-left:10px; max-width:150px\">{4}</td>" +
                                "</tr>",
                    a.Name,
                    a.RoleName,
                    a.InTime.ToString("dd-MMM-yyyy h:mm tt", CultureInfo.InvariantCulture),
                    a.OutTime?.ToString("dd-MMM-yyyy h:mm tt", CultureInfo.InvariantCulture) ?? "",
                    a.Comment);
            }

            return sb.ToString();
        }
    }

}
