public async Task<ActionResult> MassEmail(CustomEmailViewModel model)
        {
            if (model.Subject.IsEmpty() || model.Body.IsEmpty())
                return Json(new { status = 0, error = "Both a Subject and a Body must be provided." });

            int numSent;

            try
            {
                Dictionary<string, string> recipients;

                using (NickBeckyWedding db = new NickBeckyWedding())
                {
                    var query = from ra in db.RSVPAttendees
                                join r in db.RSVPs on ra.RSVP_ID equals r.ID
                                select new
                                {
                                    ra.Name,
                                    Email = ra.EmailAddress,
                                    r.Attending
                                };

                    if (model.RecipientSelection != "All") query = query.Where(r => r.Attending);

                    query = query.Distinct();

                    recipients = await query.ToDictionaryAsync(r => r.Name, r => r.Email);
                }

                numSent = await SendMassEmailAsync(model, recipients);
            }
            catch (Exception ex)
            {
                return Json(new { status = 0, error = ex.Message });
            }

            return Json(new { status = 1, message = "All " + numSent + " emails successfully sent." });
        }
        public async Task<ActionResult> Rsvp(RsvpViewModel model)
        {
            if (!string.IsNullOrWhiteSpace(model.Website) || model.CaptchaPass == null || model.CaptchaPass != "KALASHIAN_NOT_ROBOT")
            {
                return Json(new { status = 0, error = "Only humans can submit this form." });
            }

            using (NickBeckyWedding db = new NickBeckyWedding())
            using (DbContextTransaction dbTrans = db.Database.BeginTransaction())
            {
                RSVP rsvp = new RSVP
                {
                    ArrivalDate = model.ArrivalDate,
                    PrimaryEmail = model.EmailAddress,
                    Attending = model.Attending
                };

                db.RSVPs.Add(rsvp);

                try
                {
                    await db.SaveChangesAsync();
                }
                catch (Exception ex)
                {
                    dbTrans.Rollback();

                    return Json(new { status = 0, error = ex.Message });
                }

                RSVPAttendee primeAttendee = new RSVPAttendee
                {
                    EmailAddress = model.EmailAddress,
                    Name = model.Name,
                    RSVP_ID = rsvp.ID
                };

                db.RSVPAttendees.Add(primeAttendee);

                foreach (RSVPAttendee dbAttendee in model.Attendees.Where(attendee => attendee.EmailAddress != null).Select(attendee => new RSVPAttendee
                {
                    EmailAddress = attendee.EmailAddress,
                    Name = attendee.Name,
                    RSVP_ID = rsvp.ID
                }))
                {
                    db.RSVPAttendees.Add(dbAttendee);
                }

                try
                {
                    await db.SaveChangesAsync();
                    dbTrans.Commit();
                }
                catch (Exception ex)
                {
                    dbTrans.Rollback();

                    return Json(new { status = 0, error = ex.Message });
                }

                await SendRsvpEmailAsync(model);
            }

            return Json(new { status = 1 });
        }
        public async Task<ActionResult> GuestBook(GuestBookMessageViewModel model)
        {
            if (!string.IsNullOrWhiteSpace(model.Website) || model.CaptchaPass == null || model.CaptchaPass != "KALASHIAN_NOT_ROBOT")
            {
                return Json(new { status = 0, error = "Only humans can submit this form." });
            }

            using (NickBeckyWedding db = new NickBeckyWedding())
            {
                GuestBookMessage guestBook = new GuestBookMessage
                {
                    Name = model.Name,
                    Message = model.Message,
                    SignedDate = DateTime.Now
                };

                db.GuestBookMessages.Add(guestBook);

                try
                {
                    await db.SaveChangesAsync();
                }
                catch (Exception ex)
                {
                    return Json(new { status = 0, error = ex.Message });
                }
            }

            return Json(new { status = 1 });
        }
        public async Task<ActionResult> GuestBook()
        {
            using (NickBeckyWedding db = new NickBeckyWedding())
            {
                IReadOnlyList<GuestBookMessage> messages =
                    await db.GuestBookMessages.OrderByDescending(msg => msg.SignedDate).ToListAsync();

                ViewBag.Messages = messages;

                return View();
            }
        }
        public async Task<JsonResult> Read(int? id)
        {
            using (NickBeckyWedding db = new NickBeckyWedding())
            {
                switch (id)
                {
                    case 1:
                        return Json(await db.RSVPs.CountAsync(), JsonRequestBehavior.AllowGet);

                    case 2:
                        return Json(await db.RSVPs.CountAsync(x => x.Attending), JsonRequestBehavior.AllowGet);

                    case 3:
                        return Json(await db.RSVPs.CountAsync(x => !x.Attending), JsonRequestBehavior.AllowGet);
                }

                List<RsvpExistingViewModel> existingRsvps = await (from ra in db.RSVPAttendees
                                                                   join r in db.RSVPs on ra.RSVP_ID equals r.ID
                                                                   select new RsvpExistingViewModel
                                                                   {
                                                                       ID = r.ID,
                                                                       Name = ra.Name,
                                                                       EmailAddress = ra.EmailAddress,
                                                                       Attending = r.Attending,
                                                                       ArrivalDate = r.ArrivalDate
                                                                   }).ToListAsync();

                return Json(new
                {
                    data = existingRsvps
                        .Distinct()
                        .Select(x => new
                        {
                            x.ID,
                            x.Name,
                            EmailAddress = "<a href='mailto:" + x.EmailAddress + "'>" + x.EmailAddress + "</a>",
                            Attending = x.Attending ? "Yes" : "No",
                            ArrivalDate = x.ArrivalDate?.ToShortDateString() ?? "N/A"
                        })
                }, JsonRequestBehavior.AllowGet);
            }
        }