unit Api.ServiceImpl;

interface

uses
  XData.Server.Module,
  XData.Service.Common,

  IdSMTP, IdMessage, IdSSLOpenSSL, IdText, IdExplicitTLSClientServerBase,
  IdIOHandlerSocket, IdException, IdSSL, IdSMTPBase, IdGlobal, IdStack, IdWinsock2,
  IdStackConsts, IdIOHandler, IdIOHandlerStack, IdBaseComponent, System.JSON,
  IdComponent, IdTCPConnection, IdTCPClient, IdMessageClient, VCL.Forms, Api.Service;

type
  [ServiceImplementation]
  TApiService = class(TInterfacedObject, IApiService)
  public
    function SendEmail(Name, Email, Subject, Body: string): string;
    function VerifyVersion(ClientVersion: string): TJSONObject;
  end;

implementation

uses
  System.SysUtils,
  System.IniFiles,
  Common.Logging,
  Main;


function TApiService.SendEmail(Name, Email, Subject, Body: string): string;
var
  SMTP: TIdSMTP;
  Message: TIdMessage;
  SSL: TIdSSLIOHandlerSocketOpenSSL;
  IniFile: TIniFile;
  IniPath, HtmlBody: string;
begin
  IniPath := ChangeFileExt(Application.ExeName, '.ini');
  IniFile := TIniFile.Create(IniPath);
  try
    SMTP := TIdSMTP.Create(nil);
    Message := TIdMessage.Create(nil);
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP);
    try
      SMTP.IOHandler := SSL;
      SMTP.UseTLS := utUseExplicitTLS;
      SMTP.AuthType := satDefault;

      SMTP.Host := IniFile.ReadString('SMTP', 'Host', '');
      SMTP.Port := IniFile.ReadInteger('SMTP', 'Port', 0);
      SMTP.Username := IniFile.ReadString('SMTP', 'Username', '');
      SMTP.Password := IniFile.ReadString('SMTP', 'Password', '');

      SSL.SSLOptions.Method := sslvTLSv1_2;
      SSL.SSLOptions.SSLVersions := [sslvTLSv1_2];

      Message.From.Address := IniFile.ReadString('SMTP', 'EmailWebsiteUses', '');
      Message.Recipients.EmailAddresses := IniFile.ReadString('SMTP', 'RecipientEmail', '');
      Message.Subject := Subject;

      HtmlBody := Format(
        '<html>' +
        '<body style="font-family: Arial, sans-serif; font-size: 14px; color:#222;">' +
          '<h2 style="color: #2E86C1; margin: 0 0 12px 0;">New "%s" message from EM Systems Website</h2>' +
          '<p style="margin: 0 0 6px 0;"><strong>Submitted On:</strong> %s</p>' +
          '<p style="margin: 0 0 6px 0;"><strong>From:</strong> %s &lt;%s&gt;</p>' +
          '<p style="margin: 0 0 14px 0;"><strong>Subject:</strong> %s</p>' +
          '<hr style="border:0; border-top:1px solid #ddd; margin: 14px 0;">' +
          '<p style="margin: 0 0 8px 0;"><strong>Message:</strong></p>' +
          '<div style="line-height: 1.4;">%s</div>' +
        '</body>' +
        '</html>',
        [
          Subject,
          FormatDateTime('yyyy-mm-dd hh:nn AM/PM', Now),
          Name,
          Email,
          Subject,
          Body.Replace(#13#10, '<br>').Replace(#10, '<br>').Replace(#13, '<br>')
        ]
      );

      Message.Body.Text := HtmlBody;
      Message.ContentType := 'text/html';

      SMTP.Connect;
      try
        SMTP.Send(Message);
      finally
        SMTP.Disconnect;
      end;

      Logger.Log(1, Format('Contact form submitted. Name: %s, Email: %s, Subject: %s, Message: %s', [Name, Email, Subject, Body]));
    finally
      SSL.Free;
      Message.Free;
      SMTP.Free;
    end;
  finally
    IniFile.Free;
  end;

  Result := 'Email sent successfully';
end;


function TApiService.VerifyVersion(ClientVersion: string): TJSONObject;
var
  iniFile: TIniFile;
  iniPath: string;
  webClientVersion: string;
  errorMsg: string;
begin
  iniPath := ChangeFileExt(Application.ExeName, '.ini');
  iniFile := TIniFile.Create(iniPath);
  try
    webClientVersion := iniFile.ReadString('Settings', 'webClientVersion', '');
  finally
    iniFile.Free;
  end;

  errorMsg := '';
  if (webClientVersion <> '') and (ClientVersion <> webClientVersion) then
  begin
    Logger.Log(2, Format('VerifyVersion called with mismatch. Server expects %s but client is %s.',
      [webClientVersion, ClientVersion]));

    errorMsg := 'You are running the wrong version of the website, please click the button to update.';
  end;

  Result := TJSONObject.Create;
  Result.AddPair('webClientVersion', webClientVersion);
  if errorMsg <> '' then
    Result.AddPair('error', errorMsg);

  Logger.Log(2, Format('VerifyVersion: client=%s server=%s mismatch=%s',
    [ClientVersion, webClientVersion, BoolToStr(errorMsg <> '', True)]));
end;


initialization
  RegisterServiceType(TApiService);

end.

