// Form that functions as both a way to edit or add users to the database
// Author: Cameron Hayes

unit View.EditUser;

interface

uses
  System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
  WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls,
  WEBLib.DBCtrls, XData.Web.Client, WEBLib.ExtCtrls, Vcl.Menus, WEBLib.Menus;

type
  TFViewEditUser = class(TWebForm)
    WebLabel2: TWebLabel;
    WebLabel3: TWebLabel;
    lblQB: TWebLabel;
    WebLabel5: TWebLabel;
    WebLabel6: TWebLabel;
    WebLabel7: TWebLabel;
    edtConfirmPassword: TWebEdit;
    edtEmail: TWebEdit;
    edtPassword: TWebEdit;
    btnConfirm: TWebButton;
    edtFullname: TWebEdit;
    edtUsername: TWebEdit;
    XDataWebClient1: TXDataWebClient;
    btnCancel: TWebButton;
    WebTimer1: TWebTimer;
    btnConfirmChanges: TWebButton;
    pnlMessage: TWebPanel;
    lblMessage: TWebLabel;
    btnCloseNotification: TWebButton;
    lblactive: TWebLabel;
    cbStatus: TWebCheckBox;
    lblRights: TWebLabel;
    edtQB: TWebEdit;
    edtRights: TWebEdit;
    lblAccess: TWebLabel;
    cbAccess: TWebComboBox;
    lblPerspective: TWebLabel;
    edtPerspective: TWebEdit;
    procedure WebFormCreate(Sender: TObject);
    procedure btnConfirmClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
    procedure WebTimer1Timer(Sender: TObject);
    procedure btnConfirmChangesClick(Sender: TObject);
    procedure btnCloseNotificationClick(Sender: TObject);
  private
    { Private declarations }
    FMessage: string;
    Mode: string;
    Username: string;
    Password: string;
    FullName: string;
    Status: string;
    Email: string;
    Access: string;
    Rights: string;
    Perspective: string;
    QB: string;
    [async] procedure EditUser();
    [async] function AddUser(): string;
    procedure HideNotification();
    procedure ShowNotification(notification: string);
  public
    { Public declarations }
    Info: string;
    class function CreateForm(AElementID, Mode, Username, Password, Name, Status, Email,
                               Access, Rights, Perspective, QB: string): TWebForm;
  end;

var
  FViewEditUser: TFViewEditUser;

implementation

uses
Windows,
View.Main,
View.Users,
VCL.Dialogs,
ConnectionModule;

procedure TFViewEditUser.btnCancelClick(Sender: TObject);
// Cancels the edit or addition
begin
  Info := 'Failure:Changes discarded!';
  FViewMain.ShowUserForm(Info);
end;

procedure TFViewEditUser.btnCloseNotificationClick(Sender: TObject);
begin
  HideNotification;
end;

procedure TFViewEditUSer.btnConfirmChangesClick(Sender: TObject);
begin
  if Mode = 'Edit' then
    EditUser()
  else
    AddUser();
  WebTimer1.Enabled := true;
  asm
    startSpinner();
  end;
end;

function TFViewEditUser.AddUser(): string;
// Sends UserInfo over to the server so it can be added to the database
var
  userInfo: string;
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
begin
  userInfo := '&username=' + edtUsername.Text +
                  '&fullname=' + edtFullName.Text +
                  '&password=' + edtPassword.Text +
                  '&status=' + BoolToStr(cbStatus.Checked) +
                  '&email=' + edtEmail.Text +
                  '&access=' + cbAccess.Text +
                  '&newuser=' + edtUsername.Text +
                  '&rights=' + edtRights.Text +
                  '&perspective=' + edtPerspective.Text +
                  '&QB=' + edtQB.Text;

  xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser',
                      [userInfo]));
  responseString :=  TJSObject(xdcResponse.Result);
  Info := string(responseString['value']);
end;

procedure TFViewEditUser.HideNotification;
begin
  pnlMessage.ElementHandle.hidden := True;
end;

procedure TFViewEditUser.ShowNotification(Notification: string);
begin
  if Notification <> '' then
  begin
    lblMessage.Caption := Notification;
    pnlMessage.ElementHandle.hidden := False;
  end;
end;

procedure TFViewEditUser.EditUser();
// Sends EditOptions over to the server so the given user can be editted
var
  editOptions: string;
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
begin

  editOptions := 'username=' + Username +
                  '&fullname=' + edtFullName.Text +
                  '&password=' + edtPassword.Text +
                  '&status=' + BoolToStr(cbStatus.Checked) +
                  '&email=' + edtEmail.Text +
                  '&access=' + cbAccess.Text +
                  '&newuser=' + edtUsername.Text +
                  '&rights=' + edtRights.Text +
                  '&perspective=' + edtPerspective.Text +
                  '&QB=' + edtQB.Text;

  console.log(editOptions);

  xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.EditUser',
        [editOptions]));
  responseString :=  TJSObject(xdcResponse.Result);
  Info := string(responseString['value']);

end;

class function TFViewEditUser.CreateForm(AElementID, Mode, Username, Password, Name, Status, Email,
                               Access, Rights, Perspective, QB: string): TWebForm;
// Autofills known information about a user on create
  procedure AfterCreate(AForm: TObject);
  begin
    TFViewEditUser(AForm).Mode := Mode;
    TFViewEditUser(AForm).Username := Username;
    TFViewEditUser(AForm).FullName := Name;
    TFViewEditUser(AForm).Status := Status;
    TFViewEditUser(AForm).Email := Email;
    TFViewEditUser(AForm).Access := Access;
    TFViewEditUser(AForm).Rights := Rights;
    TFViewEditUser(AForm).Perspective := Perspective;
    TFViewEditUser(AForm).QB := QB;
  end;

{$R *.dfm}
begin
  Application.CreateForm(TFViewEditUser, AElementID, Result, @AfterCreate);
end;



procedure TFViewEditUser.WebFormCreate(Sender: TObject);
// Autofills known information about a user on create
begin
  if FMessage <> '' then
    ShowNotification(FMessage)
  else
    HideNotification;
  edtUsername.Text := Username;
  edtFullName.Text := FullName;
  if Mode = 'Edit' then
  begin
    edtPassword.Text := 'hidden';
    edtConfirmPassword.Text := 'hidden';
  end;
  edtEmail.Text := Email;
  cbAccess.Text := Access;
  edtRights.Text := Rights;
  edtQB.Text :=  QB;
  if Status = 'ACTIVE' then
    cbStatus.checked := true;
  edtPerspective.Text := Perspective
end;

procedure TFViewEditUser.WebTimer1Timer(Sender: TObject);
begin
  WebTimer1.Enabled := False;
  asm
    endSpinner();
  end;
  if (not Info.Contains('Failure')) then
  begin
    FViewMain.ShowUserForm(Info);
  end
  else
    showNotification(Info);
  console.log('Info at Timer:' + Info);
end;

procedure TFViewEditUser.btnConfirmClick(Sender: TObject);
// Confirms the edit or addition
var
  checkString: string;
  charIndex: integer;
  phoneNum: string;
begin
 { checkString := edtFullName.Text + edtUsername.Text + edtPassword.Text
                + edtConfirmPassword.Text + edtPhoneNumber.Text + edtEmail.Text;
  if string(edtFullName.Text).IsEmpty then
  begin
    ShowNotification('Full Name field is blank!');
    exit;
  end;

  if string(edtUsername.Text).IsEmpty then
  begin
    ShowNotification('Username field is blank!');
    exit;
  end;

  if string(edtPassword.Text).IsEmpty then
  begin
    ShowNotification('Password field is blank!');
    exit;
  end;

  if string(edtConfirmPassword.Text).IsEmpty then
  begin
    ShowNotification('Please confirm your password!');
    exit;
  end;

  if string(edtPhoneNumber.Text).IsEmpty then
  begin
    ShowNotification('Phone Number field is blank!');
    exit;
  end;

  if string(edtEmail.Text).IsEmpty then
  begin
    ShowNotification('Email field is blank!');
    exit;
  end;

  if checkString.Contains('&') then
  begin
    ShowNotification('No fields may contain "&&"!');
    exit;
  end;

  if string(edtEmail.Text).Contains('@') = false then
  begin
    ShowNotification('Please enter a valid email address');
    exit;
  end;

  if (length(string(edtEmail.Text).Split(['@'])) <> 2) or (string(edtEmail.text).CountChar('@') > 1) then
  begin
    ShowNotification('Please enter a valid email address');
    exit;
  end;

  phoneNum := edtPhoneNumber.Text;

  if (not phoneNum.Contains('(')) or (not phoneNum.Contains(')')) or (not phoneNum.Contains('-')) then
  begin
    ShowNotification('Please enter a valid phone number');
    exit;
  end;

  if (phoneNum.CountChar('(') <> 1) or (phoneNum.CountChar(')') <> 1) or (phoneNum.CountChar('-') <> 1) or (phoneNum.CountChar(' ') > 1) then
  begin
    ShowNotification('Please enter a valid phone number');
    exit;
  end;

  phoneNum := phoneNum.Replace('(', '');
  phoneNum := phoneNum.Replace(')', '');
  phoneNum := phoneNum.Replace('-', '');
  phoneNum := phoneNum.Replace(' ', '');

  if(length(phoneNum) <> 10) then
  begin
    ShowNotification('Please enter a valid phone number');
    exit;
  end;

  for CharIndex := 1 to Length(phoneNum) do
  begin
    if not (phoneNum[CharIndex] in ['0' .. '9']) then
    begin
      console.log('here');
      ShowNotification('Please enter a valid phone number');
      exit;
    end;
  end;

  if edtPassword.Text <> edtConfirmPassword.Text then
  begin
    ShowNotification('Passwords must match!');
    exit;
  end;

  if (length(edtPassword.Text) > 20) or (length(edtPassword.Text) < 6) then
  begin
    ShowNotification('Passwords must be between 6-20 characters!');
    exit;
  end;
  }
  asm
    var modal = document.getElementById('confirmation_modal');
    // ensure the modal is directly under <body>
    if (modal && modal.parentNode !== document.body) {
      document.body.appendChild(modal);
    }

    var bsModal = new bootstrap.Modal(modal, {
      keyboard: false
    });
    bsModal.show();
  end;
end;

end.
