// Search pop-up form used to filter the list.
// Author: Cameron Hayes
unit View.Search;

interface

uses
  System.SysUtils, System.Generics.Collections, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
  WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
  WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
  ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
  Data.DB, XData.Web.JsonDataset, XData.Web.Dataset, WEBLib.DB, WEBLib.Grids,
  Vcl.Grids, VCL.TMSFNCTypes, VCL.TMSFNCUtils, VCL.TMSFNCGraphics,
  VCL.TMSFNCGraphicsTypes, VCL.TMSFNCGridCell, VCL.TMSFNCGridOptions,
  VCL.TMSFNCCustomControl, VCL.TMSFNCCustomScrollControl, VCL.TMSFNCGridData,
  VCL.TMSFNCCustomGrid, VCL.TMSFNCGrid;

type
  TFSearch = class(TWebForm)
    wcbFilterType1: TWebComboBox;
    btnConfirm: TWebButton;
    edtOrderID: TWebEdit;
    dtpStartDate1: TWebDateTimePicker;
    dtpEndDate1: TWebDateTimePicker;
    cbNull1: TWebCheckBox;
    wcbOrderType: TWebComboBox;
    lblStatus1: TWebLabel;
    lblType1: TWebLabel;
    lblStartDate1: TWebLabel;
    lblEndDate1: TWebLabel;
    wcbFilterType2: TWebComboBox;
    dtpStartDate2: TWebDateTimePicker;
    dtpEndDate2: TWebDateTimePicker;
    cbNull2: TWebCheckBox;
    lblStatus2: TWebLabel;
    lblType2: TWebLabel;
    lblStartDate2: TWebLabel;
    lblEndDate2: TWebLabel;
    WebLabel1: TWebLabel;
    WebLabel2: TWebLabel;
    TMSFNCGrid1: TTMSFNCGrid;
    edtSearch: TWebEdit;
    edtCompanyID: TWebEdit;
    lblCompanyID: TWebLabel;
    XDataWebClient1: TXDataWebClient;
    xdwdsCustomers: TXDataWebDataSet;
    xdwdsCustomersNAME: TStringField;
    wdsCustomers: TWebDataSource;
    WebLabel3: TWebLabel;
    edtJobName: TWebEdit;
    WebLabel4: TWebLabel;
    btnCancel: TWebButton;
    btnClear: TWebButton;
    xdwdsCustomersstaff_fields_invoice_to: TStringField;
    WebLabel5: TWebLabel;
    edtCompanyName: TWebEdit;
    xdwdsCustomersSHORT_NAME: TStringField;
    xdwdsCustomersCUSTOMER_ID: TIntegerField;
    WebLabel6: TWebLabel;
    edtCadFile: TWebEdit;
    procedure btnConfirmClick(Sender: TObject);
    procedure WebFormShow(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
    procedure edtSearchChange(Sender: TObject);
    procedure TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
    procedure btnClearClick(Sender: TObject);
    procedure cbNull1Click(Sender: TObject);
    procedure cbNull2Click(Sender: TObject);
    procedure wcbFilterType1Change(Sender: TObject);
    procedure wcbFilterType2Change(Sender: TObject);
  private
    //FJSONProc: TJSONProc;
    [async] procedure getCustomers;
    procedure PopulateGridManually;
    procedure ApplyFilter;
  public
    class function CreateForm(AElementID: string): TWebForm;
    var
      confirm: boolean;
      searchOptions: string;
      DBID: string;
  end;

var
  FSearch: TFSearch;

implementation

{$R *.dfm}

class function TFSearch.CreateForm(AElementID: string): TWebForm;
begin
  Application.CreateForm(TFSearch, AElementID, Result,
    procedure(AForm: TObject)
    begin
      with TFSearch(AForm) do
      begin

      end;
    end
  );
end;

procedure TFSearch.edtSearchChange(Sender: TObject);
begin
  ApplyFilter;
end;

procedure TFSearch.WebFormShow(Sender: TObject);
// Auto fills information based on previous search
var
  params: TStringList;
  DateFormatSettings: TFormatSettings;
begin
  params := TStringList.Create;
  dtpStartDate1.Date := 0;
  dtpStartDate2.Date := 0;
  dtpEndDate1.Date := 0;
  dtpEndDate2.Date := 0;
  {params.StrictDelimiter := true;
  params.Delimiter := '&';
  params.DelimitedText := searchOptions;
  confirm := false;

  DateFormatSettings := TFormatSettings.Create;
  DateFormatSettings.ShortDateFormat := 'yyyy/mm/dd';
  wcbOrderType.Text := UpperCase(Copy(params.Values['orderType'], 1, 1)) + LowerCase(Copy(params.Values['orderType'], 2, MaxInt));
  edtOrderID.Text := params.Values['orderID'];
  edtJobName.Text := params.Values['jobName'];
  DBID := params.Values['companyID'];

  // Status 1
  if params.Values['filterType1'] <> '' then
    wcbFilterType1.Text := params.Values['filterType1']
  else
    wcbFilterType1.Text := 'NONE';

  if params.Values['startDate1'] = '' then
    dtpStartDate1.Date := 0
  else
  begin
    dtpStartDate1.Date := StrToDateTime(params.Values['startDate1'], DateFormatSettings);
  end;

  if params.Values['endDate1'] = '' then
    dtpEndDate1.Date := 0
  else
    dtpEndDate1.Date := StrToDateTime(params.Values['endDate1'], DateFormatSettings);

  if params.values['null1'] <> '' then
  begin
    cbNull1.Checked := StrToBool(params.Values['null1']);
    if StrToBool(params.Values['null1']) then
    begin
      dtpStartDate1.Visible := false;
      dtpEndDate1.Visible := false;
    end;
  end;

  // Status 2
  if params.Values['filterType2'] <> '' then
    wcbFilterType2.Text := params.Values['filterType2']
  else
    wcbFilterType2.Text := 'NONE';

  if params.Values['startDate2'] = '' then
    dtpStartDate2.Date := 0
  else
    dtpStartDate2.Date := StrToDateTime(params.Values['startDate2'], DateFormatSettings);

  if params.Values['endDate2'] = '' then
    dtpEndDate2.Date := 0
  else
    dtpEndDate2.Date := StrToDateTime(params.Values['endDate2'], DateFormatSettings);

  if params.values['null2'] <> '' then
  begin
    cbNull2.Checked := StrToBool(params.Values['null2']);
    if StrToBool(params.Values['null2']) then
    begin
      dtpStartDate2.Visible := false;
      dtpEndDate2.Visible := false;
    end;
  end; }

  getCustomers();

  params.Free;
end;

procedure TFSearch.btnCancelClick(Sender: TObject);
begin
  Close;
end;

procedure TFSearch.btnClearClick(Sender: TObject);
begin
  edtOrderID.Text := '';
  edtCompanyID.Text := '';
  edtCompanyName.Text := '';
  edtSearch.Text := '';
  edtJobName.Text := '';
  wcbOrderType.Text := 'Any';
  wcbFilterType1.Text := 'NONE';
  dtpStartDate1.Date := 0;
  dtpEndDate1.Date := 0;
  cbNull1.Checked := False;
  wcbFilterType2.Text := 'NONE';
  dtpStartDate2.Date := 0;
  dtpEndDate2.Date := 0;
  cbNull2.Checked := false;
  dtpStartDate1.Visible := true;
  dtpStartDate2.Visible := true;
  dtpEndDate1.Visible := true;
  dtpEndDate2.Visible := true;
  DBID := '';
end;

procedure TFSearch.btnConfirmClick(Sender: TObject);
begin
  confirm := true;
  Close;
end;

procedure TFSearch.cbNull1Click(Sender: TObject);
begin
  if cbNull1.Checked then
  begin
    dtpStartDate1.Visible := false;
    dtpEndDate1.Visible := false;
  end
  else
  begin
    dtpStartDate1.Visible := true;
    dtpEndDate1.Visible := true;
  end;
end;

procedure TFSearch.cbNull2Click(Sender: TObject);
begin
  if cbNull2.Checked then
  begin
    dtpStartDate2.Visible := false;
    dtpEndDate2.Visible := false;
  end
  else
  begin
    dtpStartDate2.Visible := true;
    dtpEndDate2.Visible := true;
  end;
end;

[async] procedure TFSearch.getCustomers();
// Gets a list of customers from the server
var
  xdcResponse: TXDataClientResponse;
  customerList: TJSObject;
begin
  // Fetch data from XData service
  xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', []));
  customerList := TJSObject(xdcResponse.Result);

  // Load data into TXDataWebDataset
  xdwdsCustomers.Close;
  xdwdsCustomers.SetJsonData(customerList['data']);
  xdwdsCustomers.Open;

  // Manually populate the grid
  PopulateGridManually;

  if DBID <> '' then
  begin
    xdwdsCustomers.Locate('CUSTOMER_ID', DBID, []);
    edtCompanyID.Text := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
    edtCompanyName.Text := xdwdsCustomers.FieldByName('NAME').AsString;
  end;
end;

procedure TFSearch.TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
begin
  edtCompanyID.Text := TMSFNCGrid1.Cells[1, ARow];
  edtCompanyName.Text := TMSFNCGrid1.Cells[2, ARow];
  DBID := TMSFNCGrid1.Cells[0, ARow];

end;

procedure TFSearch.wcbFilterType1Change(Sender: TObject);
begin
  if wcbFilterType1.Text = 'NONE' then
  begin
    dtpStartDate1.Visible := false;
    dtpEndDate1.Visible := false;
    cbNull1.Visible := false;
  end
  else
  begin
    dtpStartDate1.Visible := True;
    dtpEndDate1.Visible := True;
    cbNull1.Visible := True;
  end;

end;

procedure TFSearch.wcbFilterType2Change(Sender: TObject);
begin
  if wcbFilterType2.Text = 'NONE' then
  begin
    dtpStartDate2.Visible := false;
    dtpEndDate2.Visible := false;
    cbNull2.Visible := false;
  end
  else
  begin
    dtpStartDate2.Visible := True;
    dtpEndDate2.Visible := True;
    cbNull2.Visible := True;
  end;
end;

procedure TFSearch.PopulateGridManually;
var
  RowIndex: Integer;
begin
  TMSFNCGrid1.BeginUpdate;
  try
    TMSFNCGrid1.Clear; // Clear any existing data

    // Set up column headers
    TMSFNCGrid1.ColumnCount := 4;
    TMSFNCGrid1.RowCount := 1;
    TMSFNCGrid1.Cells[0, 0] := 'Customer Num';
    TMSFNCGrid1.Cells[1, 0] := 'Customer ID';
    TMSFNCGrid1.Cells[2, 0] := 'Customer Name';
    TMSFNCGrid1.Cells[3, 0] := 'Address';

    // Populate the grid with data from the dataset
    xdwdsCustomers.First;
    RowIndex := 1;

    while not xdwdsCustomers.EOF do
    begin
      TMSFNCGrid1.RowCount := RowIndex + 1;
      TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('CUSTOMER_ID').AsString;
      TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
      TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString;
      TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('staff_fields_invoice_to').AsString;

      Inc(RowIndex);
      xdwdsCustomers.Next;
    end;

  finally
    TMSFNCGrid1.EndUpdate;
  end;
end;

procedure TFSearch.ApplyFilter;
var
  fd: TTMSFNCGridFilterData;
  i: Integer;
  SearchText: string;
begin
  SearchText := Trim(edtSearch.Text);

  TMSFNCGrid1.RemoveFilter;
  TMSFNCGrid1.Filter.Clear;

  // match on first 3 columns
  for i := 0 to 2 do
  begin
    fd := TMSFNCGrid1.Filter.Add;
    fd.Column := i;
    fd.Condition := '*' + SearchText + '*'; // Match text anywhere in the cell
    fd.CaseSensitive := False; // Make the filter case-insensitive

    // Use foOR for "match any column" logic
    if i > 0 then
      fd.Operation := foOR
    else
      fd.Operation := foNONE; // First filter has no logical operation
  end;

  // Apply the filters to the grid
  TMSFNCGrid1.ApplyFilter;
end;

end.

