unit View.Users;

interface

uses
  System.SysUtils, System.Classes, Web, WEBLib.Graphics, WEBLib.Forms, WEBLib.Dialogs,
  Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, WEBLib.Controls, WEBLib.Grids, WebLib.Lists,
  XData.Web.Client, WEBLib.ExtCtrls, DB, XData.Web.JsonDataset,
  XData.Web.Dataset, XData.Web.Connection, Vcl.Forms, WEBLib.DBCtrls, JS, Utils;

type
  TFViewUsers = class(TWebForm)
    XDataWebClient1: TXDataWebClient;
    XDataWebDataSet1: TXDataWebDataSet;
    lblEntries: TWebLabel;
    btnAddUser: TWebButton;
    WebDataSource1: TWebDataSource;
    XDataWebDataSet1userID: TStringField;
    XDataWebDataSet1username: TStringField;
    XDataWebDataSet1full_name: TStringField;
    XDataWebDataSet1password: TStringField;
    XDataWebDataSet1status: TStringField;
    XDataWebDataSet1email_address: TStringField;
    XDataWebDataSet1Atype: TStringField;
    XDataWebDataSet1rights: TIntegerField;
    XDataWebDataSet1perspectiveID: TStringField;
    XDataWebDataSet1QBID: TStringField;
    procedure WebFormCreate(Sender: TObject);
    //procedure tblPhoneGridGetCellChildren(Sender: TObject; ACol, ARow: Integer;
      //AField: TField; AValue: string; AElement: TJSHTMLElementRecord);
    procedure btnConfirmDeleteClick(Sender: TObject);
    procedure btnAddUserClick(Sender: TObject);
    //procedure btnApplyClick(Sender: TObject);
    //procedure btnSearchClick(Sender: TObject);
  private
    FChildForm: TWebForm;
    procedure ClearTable();
    procedure GeneratePagination(TotalPages: Integer);
    //function GenerateSearchOptions(): string;
    //[async] procedure Search(searchOptions: string);
    [async] procedure DelUser(username: string);
    [async] procedure EditUser(row: TJSHTMLElement);
    [async] procedure GetUsers(searchOptions: string);
    procedure AddRowToTable(UserID, Username, Password, Full_Name, Status,
                        Email, AType, PID, QBID: string; Rights: integer);
    //[async] procedure addUser();
    var
      PageNumber: integer;
      PageSize: integer;
      TotalPages: integer;
      StartDate: string;
      EndDate: string;
      OrderBy: string;
      cur_user: string;
      Info: string;
  public
  class function CreateForm(AElementID, Info: string): TWebForm;
  end;

var
  FViewUsers: TFViewUsers;

implementation

{$R *.dfm}

uses
  XData.Model.Classes,
  ConnectionModule,
  View.Main;

{$R *.dfm}

class function TFViewUsers.CreateForm(AElementID, Info: string): TWebForm;
// Autofills known information about a user on create
  procedure AfterCreate(AForm: TObject);
  begin
    TFViewUsers(AForm).Info := Info;
  end;

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

procedure TFViewUsers.WebFormCreate(Sender: TObject);
begin
  DMConnection.ApiConnection.Connected := True;
  PageNumber := 1;
  TotalPages := 1; // Initial total pages
  PageSize := 10;
  GetUsers('');
  if Info <> '' then
    ShowToast(Info)
end;

procedure TFViewUsers.DelUser(username: string);
var
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
begin
    xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.DelUser',
        [username]));
    responseString :=  TJSObject(xdcResponse.Result);
    ShowToast(string(responseString['value']));
    getUsers('');
end;

procedure TFViewUsers.EditUser(row: TJSHTMLElement);
var
  cells: TJSHTMLCollection;
  UserID: TJSNode;
  Username: TJSNode;
  Password: TJSNode;
  FullName: TJSNode;
  Status: TJSNode;
  Email: TJSNode;
  Access: TJSNode;
  Rights: TJSNode;
  QB: TJSNode;
  isAdmin: boolean;
  isActive: boolean;
  ButtonCancel: TJSHTMLElement;
  splitNames: TArray<string>;
  firstName: string;
  lastName: string;
  xdcResponse: TXDataClientResponse;
  responseString: TJSObject;
  editOptions: string;

begin
  cells := row.getElementsByTagName('td');
  UserID := cells[0];
  Username := cells[1];
  Password := cells[2];
  FullName := cells[3];
  Status := cells[4];
  Email := cells[5];
  Access := cells[6];
  Rights := cells[7];
  QB := cells[8];

  FViewMain.EditUser('EDIT', Username.innerText, Password.innerText, FullName.innerText,
                    Status.innerText, Email.innerText, Access.innerText,
                    Rights.innerText, QB.innerText);

end;

procedure TFViewUsers.GeneratePagination(TotalPages: Integer);
var
  PaginationElement, PageItem, PageLink: TJSHTMLElement;
  I, Start, Finish: Integer;
begin
  PaginationElement := TJSHTMLElement(document.getElementById('pagination'));
  PaginationElement.innerHTML := ''; // Clear existing pagination

  // Previous Button
  PageItem := TJSHTMLElement(document.createElement('li'));
  PageItem.className := 'page-item';
  if PageNumber = 1 then
    PageItem.classList.add('disabled');
  PageLink := TJSHTMLElement(document.createElement('a'));
  PageLink.className := 'page-link';
  PageLink.innerText := 'Previous';
  PageLink.setAttribute('href', 'javascript:void(0)');
  PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
  begin
    if PageNumber > 1 then
    begin
      Dec(PageNumber);
      GetUsers('');
    end;
  end);
  PageItem.appendChild(PageLink);
  PaginationElement.appendChild(PageItem);

  // Page Numbers

  if PageNumber <= 4 then
  Begin
    Start := 2;
    Finish := 5;
  End
  else if (PageNumber >= (TotalPages - 3)) then
  begin
    Start := TotalPages - 3;
    Finish := TotalPages - 1;
  end
  else
  begin
    Start := PageNumber - 1;
    Finish := PageNumber + 1;
  end;

  PageItem := TJSHTMLElement(document.createElement('li'));
  PageItem.className := 'page-item';
  if 1 = PageNumber then
    PageItem.classList.add('selected-number'); // Add the selected-number class
  PageLink := TJSHTMLElement(document.createElement('a'));
  PageLink.className := 'page-link';
  PageLink.innerText := '1';
  PageLink.setAttribute('href', 'javascript:void(0)');
  PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
  var
    PageNum: Integer;
  begin
    PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
    PageNumber := PageNum;
    GetUsers('');
  end);
  PageItem.appendChild(PageLink);
  PaginationElement.appendChild(PageItem);

  // Adds Elipse to pagination if page number is too big
  if PageNumber > 4 then
  begin
    PageItem := TJSHTMLElement(document.createElement('li'));
    PageItem.className := 'page-item';
    PageItem.classList.add('disabled');
    PageLink := TJSHTMLElement(document.createElement('a'));
    PageLink.className := 'page-link';
    PageLink.innerText := '...';
    PageLink.setAttribute('href', 'javascript:void(0)');
    PageItem.appendChild(PageLink);
    PaginationElement.appendChild(PageItem);
  end;


  // Adds Page, page - 1, and page + 1 to pagination
  for I := Start  to Finish do
  begin
    if ( I > 1) and (I < TotalPages) then
    begin
      PageItem := TJSHTMLElement(document.createElement('li'));
      PageItem.className := 'page-item';
      if I = PageNumber then
        PageItem.classList.add('selected-number'); // Add the selected-number class
      PageLink := TJSHTMLElement(document.createElement('a'));
      PageLink.className := 'page-link';
      PageLink.innerText := IntToStr(I);
      PageLink.setAttribute('href', 'javascript:void(0)');
      PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
      var
        PageNum: Integer;
      begin
        PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
        PageNumber := PageNum;
        GetUsers('');
      end);
      PageItem.appendChild(PageLink);
      PaginationElement.appendChild(PageItem);
    end;
  end;

  if PageNumber < TotalPages - 4 then
  begin
    PageItem := TJSHTMLElement(document.createElement('li'));
    PageItem.className := 'page-item';
    PageItem.classList.add('disabled');
    PageLink := TJSHTMLElement(document.createElement('a'));
    PageLink.className := 'page-link';
    PageLink.innerText := '...';
    PageLink.setAttribute('href', 'javascript:void(0)');
    PageItem.appendChild(PageLink);
    PaginationElement.appendChild(PageItem);
  end;

  if TotalPages <> 1 then
  begin
    PageItem := TJSHTMLElement(document.createElement('li'));
    PageItem.className := 'page-item';
    if TotalPages = PageNumber then
          PageItem.classList.add('selected-number');
    PageLink := TJSHTMLElement(document.createElement('a'));
    PageLink.className := 'page-link';
    PageLink.innerText := IntToStr(TotalPages);
    PageLink.setAttribute('href', 'javascript:void(0)');
    PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
    var
      PageNum: Integer;
    begin
      PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
      PageNumber := PageNum;
      GetUsers('');
    end);
    PageItem.appendChild(PageLink);
    PaginationElement.appendChild(PageItem);
  end;

  // Next Button
  PageItem := TJSHTMLElement(document.createElement('li'));
  PageItem.className := 'page-item';
  if PageNumber = TotalPages then
    PageItem.classList.add('disabled');
  PageLink := TJSHTMLElement(document.createElement('a'));
  PageLink.className := 'page-link';
  PageLink.innerText := 'Next';
  PageLink.setAttribute('href', 'javascript:void(0)');
  PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
  begin
    if PageNumber < TotalPages then
    begin
      Inc(PageNumber);
      GetUsers('');
    end;
  end);
  PageItem.appendChild(PageLink);
  PaginationElement.appendChild(PageItem);

end;


procedure TFViewUsers.GetUsers(searchOptions: string);
var
  xdcResponse: TXDataClientResponse;
  userList : TJSObject;
  i: integer;
  data: TJSArray;
  user: TJSObject;
  userListLength: integer;
begin
  if PageNumber > 0 then
  begin
    Utils.ShowSpinner('spinner');
    try
      xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetUsers',
          [searchOptions]));

      userList :=  TJSObject(xdcResponse.Result);
      data := TJSArray(userList['data']);
      userListLength := integer(userList['count']);
      ClearTable();
      XDataWebDataSet1.Close;
      XDataWebDataSet1.SetJsonData(userList['data']);
      XDataWebDataSet1.Open;
      for i := 0 to data.Length - 1 do
      begin
        user := TJSObject(data[i]);
        AddRowToTable(XDataWebDataSet1userID.AsString, XDataWebDataSet1username.AsString,
                      XDataWebDataSet1password.AsString, XDataWebDataSet1full_name.AsString,
                      XDataWebDataSet1status.AsString, XDataWebDataSet1email_address.AsString,
                      XDataWebDataSet1Atype.AsString, XDataWebDataSet1perspectiveID.AsString,
                      XDataWebDataSet1QBID.AsString, XDataWebDataSet1rights.AsInteger);
        XDataWebDataSet1.Next;
      end;
      lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
                              ' - ' + IntToStr(userListLength) +
                              ' of ' + IntToStr(userListLength);
    except
      on E: EXDataClientRequestException do
        Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
    end;
    Utils.HideSpinner('spinner');
  end;
end;

procedure TFViewUsers.AddRowToTable(UserID, Username, Password, Full_Name, Status,
                        Email, AType, PID, QBID: string; Rights: integer);
// Adds rows to the table
// PhoneNumber: phone number of the location
// Caller: phone number of the caller
// Duration: duration of the call
// Transcript: transcription of the recording
// MediaUrl: Link to the recording
var
  NewRow, Cell, P, Button, cbAdmin: TJSHTMLElement;
begin
  NewRow := TJSHTMLElement(document.createElement('tr'));

  // UserID  Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'UserID');
  Cell.innerText := UserID;
  NewRow.appendChild(Cell);

  // Username Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Username');
  Cell.innerText := Username;
  NewRow.appendChild(Cell);

  // Password Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Password');
  Cell.innerText := 'hidden';
  NewRow.appendChild(Cell);

  // Full Name Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Full Name');
  Cell.innerText := Full_Name;
  NewRow.appendChild(Cell);

  // Status Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Status');
  Cell.innerText := Status;
  NewRow.appendChild(Cell);

  // Email Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Email Address');
  Cell.innerText := Email;
  NewRow.appendChild(Cell);

  //Access Type Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Access Type');
  Cell.innerText := AType;
  NewRow.appendChild(Cell);


  // System Rights Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'System Rights');
  Cell.innerText := IntToStr(Rights);
  NewRow.appendChild(Cell);

  // QB ID Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'QB ID');
  Cell.innerText := QBID;
  NewRow.appendChild(Cell);

  // Edit Cell
  Cell := TJSHTMLElement(document.createElement('td'));
  Cell.setAttribute('data-label', 'Edit');
  Button := TJSHTMLElement(document.createElement('a'));
  Button.className := 'btn btn-sm btn-primary';
  Button.innerHTML := '<i class="far fa-edit fa-fw"></i><span>Edit</span>';
  Button.addEventListener('click', procedure(Event: TJSMouseEvent)
  begin
    EditUser(TJSHTMLElement(NewRow));
  end);
  Cell.appendChild(Button);
  NewRow.appendChild(Cell);

  // Appends new rows to the table body
  TJSHTMLElement(document.getElementById('tblPhoneGrid').getElementsByTagName('tbody')[0]).appendChild(NewRow);
end;

procedure TFViewUsers.btnAddUserClick(Sender: TObject);
begin
  //Info := '';
  FViewMain.EditUser('ADD', '', '', '', '', '', '', '', '');
end;


procedure TFViewUsers.btnConfirmDeleteClick(Sender: TObject);
begin
  DelUser(cur_user);
end;

procedure TFViewUsers.ClearTable();
var
  tbody: TJSHTMLElement;
begin
  tbody := TJSHTMLElement(document.getElementById('tblPhoneGrid').getElementsByTagName('tbody')[0]);
  tbody.innerHTML := '';
end;

end.
