unit View.ComplaintArchive;

interface

uses
  System.SysUtils, System.Classes, JS, Web,
  WEBLib.Graphics, WEBLib.Controls, WEBLib.Forms, WEBLib.Dialogs,
  Vcl.Controls, Vcl.StdCtrls, Data.DB,
  WEBLib.StdCtrls, WEBLib.Grids, WEBLib.DBCtrls, WEBLib.DB,
  XData.Web.Client, XData.Web.JsonDataset, XData.Web.Dataset,
  ConnectionModule;

type
  TFViewComplaintArchive = class(TWebForm)
    tblRemarksArc: TWebDBTableControl;
    xdwcComplaintArchive: TXDataWebClient;
    xdwdsRemarksArc: TXDataWebDataSet;
    xdwdsRemarksArcMemoId: TStringField;
    xdwdsRemarksArcCFSId: TStringField;
    xdwdsRemarksArcMemoType: TStringField;
    xdwdsRemarksArcTimestamp: TStringField;
    xdwdsRemarksArcBadgeNumber: TStringField;
    xdwdsRemarksArcRemarks: TStringField;
    wdsRemarksArc: TWebDataSource;
    btnUntArc: TWebButton;
    btnREMArc: TWebButton;
    btnE911Arc: TWebButton;
    btnCmpArc: TWebButton;
    btnComplaintViewOnMapArc: TWebButton;
    procedure WebFormCreate(Sender: TObject);
    procedure btnCmpArcClick(Sender: TObject);
    procedure btnE911ArcClick(Sender: TObject);
    procedure btnREMArcClick(Sender: TObject);
    procedure btnUntArcClick(Sender: TObject);
    procedure btnComplaintViewOnMapArcClick(Sender: TObject);
  private
    FComplaintId: string;
    FCfsId: string;

    FAllMemos: TJSArray;

    FShowCMP: Boolean;
    FShowE911: Boolean;
    FShowREM: Boolean;
    FShowUNT: Boolean;

    procedure WireUi;
    procedure SetTextById(const Id, Value: string);
    procedure SetHiddenById(const Id: string; Hidden: Boolean);
    procedure SetButtonActive(aButton: TWebButton; Active: Boolean);

    [async] procedure LoadArchiveAsync;
    [async] procedure LoadMemosAsync;

    procedure ApplyMemoFilters;

    function GetMemoTypeCode(const MemoType: string): string;
    function MemoTypeLabel(const MemoType: string): string;
  public
    class function CreateForm(const AHostId, AComplaintId: string): TFViewComplaintArchive;
  end;

implementation

uses
  View.Main;

{$R *.dfm}

class function TFViewComplaintArchive.CreateForm(const AHostId, AComplaintId: string): TFViewComplaintArchive;
begin
  Result := TFViewComplaintArchive(inherited CreateNew(AHostId));
  Result.FComplaintId := AComplaintId;
end;

procedure TFViewComplaintArchive.WebFormCreate(Sender: TObject);
begin
  FAllMemos := nil;

  FShowCMP := True;
  FShowE911 := True;
  FShowREM := True;
  FShowUNT := True;

  WireUi;
  LoadArchiveAsync;
end;

procedure TFViewComplaintArchive.WireUi;
begin
  // Nothing required here beyond component OnClick handlers;
  // all element IDs are bound via the DFM.
end;

procedure TFViewComplaintArchive.SetTextById(const Id, Value: string);
var
  el: TJSElement;
begin
  el := Document.getElementById(Id);
  if el <> nil then
    el.innerHTML := Value;
end;

procedure TFViewComplaintArchive.SetHiddenById(const Id: string; Hidden: Boolean);
var
  el: TJSHTMLElement;
begin
  el := TJSHTMLElement(Document.getElementById(Id));
  if el = nil then
    Exit;

  if Hidden then
    el.classList.add('d-none')
  else
    el.classList.remove('d-none');
end;

procedure TFViewComplaintArchive.SetButtonActive(aButton: TWebButton; Active: Boolean);
var
  el: TJSHTMLElement;
begin
  if (aButton = nil) or (aButton.ElementHandle = nil) then
    Exit;

  el := TJSHTMLElement(aButton.ElementHandle);

  if Active then
  begin
    el.classList.add('active');
    el.setAttribute('aria-pressed', 'true');
  end
  else
  begin
    el.classList.remove('active');
    el.setAttribute('aria-pressed', 'false');
  end;
end;

[async] procedure TFViewComplaintArchive.LoadArchiveAsync;
var
  resp: TXDataClientResponse;
  rootObj: TJSObject;
  dataObj: TJSObject;
  business: string;
begin
  resp := await(xdwcComplaintArchive.RawInvokeAsync('IApiService.GetComplaintArchiveDetails', [FComplaintId]));
  rootObj := TJSObject(resp.Result);
  dataObj := TJSObject(rootObj['data']);

  // Summary title (optional)
  SetTextById('lbl_summary_title_arc', 'Summary');

  SetTextById('lbl_priority_arc', string(dataObj['Priority']));
  SetTextById('lbl_dispatch_code_arc', string(dataObj['DispatchCodeDesc']));
  SetTextById('lbl_dispatch_district_arc', string(dataObj['DispatchDistrict']));
  SetTextById('lbl_address_arc', string(dataObj['Address']));

  business := string(dataObj['Business']);
  if business <> '' then
  begin
    SetTextById('lbl_business_arc', business);
    SetHiddenById('row_business_arc', False);
  end
  else
    SetHiddenById('row_business_arc', True);

  // Status: same logic style as details; simplest is derive from timestamps if you want,
  // but archive view can just show blank unless you prefer the full logic.
  // If your archive endpoint includes a computed Status, you can display it directly.
  if dataObj.hasOwnProperty('Status') then
    SetTextById('lbl_status_arc', string(dataObj['Status']))
  else
    SetTextById('lbl_status_arc', '');

  // CFSId is needed for memos
  FCfsId := string(dataObj['CFSId']);

  await(LoadMemosAsync);
end;

function TFViewComplaintArchive.MemoTypeLabel(const MemoType: string): string;
var
  c: string;
begin
  c := GetMemoTypeCode(MemoType);
  if c = 'CMP' then Exit('CMP');
  if c = 'E911' then Exit('E-911');
  if c = 'REM' then Exit('REM');
  if c = 'UNT' then Exit('UNT');
  Result := MemoType;
end;

function TFViewComplaintArchive.GetMemoTypeCode(const MemoType: string): string;
var
  mt: string;
begin
  mt := LowerCase(Trim(MemoType));

  // Match whatever your server returns in GetComplaintMemos:
  // Keep these mappings aligned with ComplaintDetails.
  if (mt = 'cmp') or (mt = 'complaint') then Exit('CMP');
  if (mt = 'e-911') or (mt = 'e911') then Exit('E911');
  if (mt = 'rem') or (mt = 'remarks') then Exit('REM');
  if (mt = 'unt') or (mt = 'unit') then Exit('UNT');

  Result := UpperCase(mt);
end;

[async] procedure TFViewComplaintArchive.LoadMemosAsync;
var
  resp: TXDataClientResponse;
  rootObj: TJSObject;
  dataArr: TJSArray;
  i: Integer;
  memoObj: TJSObject;
  memoType: string;
begin
  // Reset dataset
  xdwdsRemarksArc.Close;

  resp := await(xdwcComplaintArchive.RawInvokeAsync('IApiService.GetComplaintMemos', [FCfsId]));
  rootObj := TJSObject(resp.Result);
  dataArr := TJSArray(rootObj['data']);

  // Save master array for filtering
  FAllMemos := dataArr;

  // Add/normalize memo type label/code (client-side)
  for i := 0 to dataArr.length - 1 do
  begin
    memoObj := TJSObject(dataArr[i]);
    memoType := string(memoObj['MemoType']);
    memoObj['MemoTypeCode'] := GetMemoTypeCode(memoType);
    memoObj['MemoType'] := MemoTypeLabel(memoType);
  end;

  ApplyMemoFilters;
end;

procedure TFViewComplaintArchive.ApplyMemoFilters;
var
  filtered: TJSArray;
  i: Integer;
  memoObj: TJSObject;
  code: string;
  ok: Boolean;
begin
  if FAllMemos = nil then
    Exit;

  filtered := TJSArray.new;

  for i := 0 to FAllMemos.length - 1 do
  begin
    memoObj := TJSObject(FAllMemos[i]);
    code := string(memoObj['MemoTypeCode']);

    ok := False;
    if (code = 'CMP') and FShowCMP then ok := True;
    if (code = 'E911') and FShowE911 then ok := True;
    if (code = 'REM') and FShowREM then ok := True;
    if (code = 'UNT') and FShowUNT then ok := True;

    if ok then
      filtered.push(memoObj);
  end;

  xdwdsRemarksArc.SetJsonData(filtered);
  xdwdsRemarksArc.Open;
end;

procedure TFViewComplaintArchive.btnCmpArcClick(Sender: TObject);
begin
  FShowCMP := not FShowCMP;
  SetButtonActive(btnCmpArc, FShowCMP);
  ApplyMemoFilters;
end;

procedure TFViewComplaintArchive.btnE911ArcClick(Sender: TObject);
begin
  FShowE911 := not FShowE911;
  SetButtonActive(btnE911Arc, FShowE911);
  ApplyMemoFilters;
end;

procedure TFViewComplaintArchive.btnREMArcClick(Sender: TObject);
begin
  FShowREM := not FShowREM;
  SetButtonActive(btnREMArc, FShowREM);
  ApplyMemoFilters;
end;

procedure TFViewComplaintArchive.btnUntArcClick(Sender: TObject);
begin
  FShowUNT := not FShowUNT;
  SetButtonActive(btnUntArc, FShowUNT);
  ApplyMemoFilters;
end;

procedure TFViewComplaintArchive.btnComplaintViewOnMapArcClick(Sender: TObject);
begin
  if Assigned(FViewMain) then
    FViewMain.ShowMapFocusComplaint(FComplaintId);
end;

end.
