context: using CmsData;
  using CmsData.API;
  using CmsData.Codes;
  using CmsData.Registration;
  using CmsWeb.Areas.OnlineReg.Models;
  using System;
  using System.Linq;
  using System.Net.Mail;
  using System.Web.Mvc;
  using UtilityExtensions;
  
  namespace CmsWeb.Areas.OnlineReg.Controllers
  {
      public partial class OnlineRegController
      {
          private const string registerlinkSTR = "RegisterLink";
          private const string votelinkSTR = "VoteLink";
          private const string rsvplinkSTR = "RsvpLink";
          private const string sendlinkSTR = "SendLink";
          private const string landingSTR = "Landing";
          private const string confirmSTR = "Confirm";
  
          public ActionResult VoteLinkSg(string id, string message, bool? confirm)
          {
              var li = new LinkInfo(CurrentDatabase, votelinkSTR, landingSTR, id);
              if (li.error.HasValue())
              {
                  return Message(li.error);
              }
  
              ViewBag.Id = id;
              ViewBag.Message = message;
              ViewBag.Confirm = confirm.GetValueOrDefault().ToString();
  
              var smallgroup = li.a[4];
              DbUtil.LogActivity($"{votelinkSTR}{landingSTR}: {smallgroup}", li.oid, li.pid);
              return View("Other/VoteLinkSg");
          }
  
          [HttpPost]
          public ActionResult VoteLinkSg(string id, string message, bool? confirm, FormCollection formCollection)
          {
              var li = new LinkInfo(CurrentDatabase, votelinkSTR, confirmSTR, id);
              if (li.error.HasValue())
              {
                  return Message(li.error);
              }
  
              try
              {
                  var smallgroup = li.a[4];
  
                  if (!li.oid.HasValue)
                  {
                      throw new Exception("orgid missing");
                  }
  
                  if (!li.pid.HasValue)
                  {
                      throw new Exception("peopleid missing");
                  }
  
                  var q = (from pp in CurrentDatabase.People
                           where pp.PeopleId == li.pid
                           let org = CurrentDatabase.Organizations.SingleOrDefault(oo => oo.OrganizationId == li.oid)
                           let om = CurrentDatabase.OrganizationMembers.SingleOrDefault(oo => oo.OrganizationId == li.oid && oo.PeopleId == li.pid)
                           select new { p = pp, org, om }).Single();
  
                  if (q.org == null && CurrentDatabase.Host == "trialdb")
                  {
                      var oid = li.oid + Util.TrialDbOffset;
                      q = (from pp in CurrentDatabase.People
                           where pp.PeopleId == li.pid
                           let org = CurrentDatabase.Organizations.SingleOrDefault(oo => oo.OrganizationId == oid)
                           let om = CurrentDatabase.OrganizationMembers.SingleOrDefault(oo => oo.OrganizationId == oid && oo.PeopleId == li.pid)
                           select new { p = pp, org, om }).Single();
                  }
  
                  if (q.org == null)
                  {
                      throw new Exception("org missing, bad link");
                  }
                  if ((q.org.RegistrationTypeId ?? RegistrationTypeCode.None) == RegistrationTypeCode.None)
                  {
                      throw new Exception("votelink is no longer active");
                  }
  
                  if (q.om == null && q.org.Limit <= q.org.RegLimitCount(CurrentDatabase))
                  {
                      throw new Exception("sorry, maximum limit has been reached");
                  }
  
                  if (q.om == null &&
                      (q.org.RegistrationClosed == true || q.org.OrganizationStatusId == OrgStatusCode.Inactive))
                  {
                      throw new Exception("sorry, registration has been closed");
                  }
  
                  var setting = CurrentDatabase.CreateRegistrationSettings(li.oid.Value);
                  if (IsSmallGroupFilled(setting, li.oid.Value, smallgroup))
                  {
                      throw new Exception("sorry, maximum limit has been reached for " + smallgroup);
                  }
  
                  var omb = OrganizationMember.Load(CurrentDatabase, li.pid.Value, li.oid.Value) ??
                            OrganizationMember.InsertOrgMembers(CurrentDatabase,
                                li.oid.Value, li.pid.Value, MemberTypeCode.Member, Util.Now.ToTimeZone(CurrentDatabase.TimeZone), null, false);
                  
                  if (q.org.AddToSmallGroupScript.HasValue())
                  {
                      var script = CurrentDatabase.Content(q.org.AddToSmallGroupScript);
                      if (script != null && script.Body.HasValue())
                      {
                          try
                          {
                              var pe = new PythonModel(CurrentDatabase.Host, "RegisterEvent", script.Body) { ScriptName = script.Name };
                              pe.instance.AddToSmallGroup(smallgroup, omb);
                          }
                          catch (Exception)
                          {
                          }
                      }
                  }
                  omb.AddToGroup(CurrentDatabase, smallgroup);
                  li.ot.Used = true;
                  CurrentDatabase.SubmitChanges();
  
                  DbUtil.LogActivity($"{votelinkSTR}{confirmSTR}: {smallgroup}", li.oid, li.pid);
  
                  if (confirm == true)
                  {
                      var subject = Util.PickFirst(setting.Subject, "no subject");
                      var msg = Util.PickFirst(setting.Body, "no message");
                      msg = APIOrganization.MessageReplacements(CurrentDatabase, q.p, q.org.DivisionName, q.org.OrganizationId, q.org.OrganizationName, q.org.Location, msg);
                      msg = msg.Replace("{details}", smallgroup);
                      var NotifyIds = CurrentDatabase.StaffPeopleForOrg(q.org.OrganizationId);
  
                      try
                      {
                          CurrentDatabase.Email(NotifyIds[0].FromEmail, q.p, subject, msg); // send confirmation
                      }
                      catch (Exception ex)
                      {
                          CurrentDatabase.Email(q.p.FromEmail, NotifyIds,
                              q.org.OrganizationName,
                              "There was a problem sending confirmation from org: " + ex.Message);
                      }
                      CurrentDatabase.Email(q.p.FromEmail, NotifyIds,
                          q.org.OrganizationName,
                          $"{q.p.Name} has registered for {q.org.OrganizationName}<br>{smallgroup}<br>(from votelink)");
                  }
              }
              catch (Exception ex)
              {
                  DbUtil.LogActivity($"{votelinkSTR}{confirmSTR}Error: {ex.Message}", li.oid, li.pid);
                  return Message(ex.Message);
              }
  
              return Message(message);
          }
  
          public ActionResult RsvpLinkSg(string id, string message, bool? confirm, bool regrets = false)
          {
              var li = new LinkInfo(CurrentDatabase, rsvplinkSTR, landingSTR, id, false);
              if (li.error.HasValue())
              {
                  return Message(li.error);
              }
  
              ViewBag.Id = id;
              ViewBag.Message = message;
              ViewBag.Confirm = confirm.GetValueOrDefault().ToString();
              ViewBag.Regrets = regrets.ToString();
  
              DbUtil.LogActivity($"{rsvplinkSTR}{landingSTR}: {regrets}", li.oid, li.pid);
              return View("Other/RsvpLinkSg");
          }
  
          [HttpPost]
          public ActionResult RsvpLinkSg(string id, string message, bool? confirm, FormCollection formCollection, bool regrets = false)
          {
              var li = new LinkInfo(CurrentDatabase, rsvplinkSTR, landingSTR, id, false);
              if (li.error.HasValue())
              {
                  return Message(li.error);
              }
  
              try
              {
                  if (!li.pid.HasValue)
                  {
                      throw new Exception("missing peopleid");
                  }
  
                  var meetingid = li.a[0].ToInt();
                  var emailid = li.a[2].ToInt();
                  var smallgroup = li.a[3];
                  if (meetingid == 0 && li.a[0].EndsWith(".next"))
                  {
                      var orgid = li.a[0].Split('.')[0].ToInt();
                      var nextmeet = (from mm in CurrentDatabase.Meetings
                                      where mm.OrganizationId == orgid
                                      where mm.MeetingDate > DateTime.Now
                                      orderby mm.MeetingDate
                                      select mm).FirstOrDefault();
                      if (nextmeet == null)
                      {
  
gt:                         return Message("no meeting");