unit uSifEventLogger;

interface

uses
  System.SysUtils, System.Classes, Data.DB, FireDAC.Comp.Client,
  uVeriFactuTypes;

type
  /// <summary>
  /// Servicio de registro de eventos del sistema (Audit Log SIF)
  /// requerido por la Orden HAC/1177/2024 para registrar arranques,
  /// paradas, cambios de configuracion y anomalias.
  /// </summary>
  TSifEventLogger = class
  private
    FConnection: TFDConnection;
  public
    constructor Create(AConnection: TFDConnection);

    /// <summary>Registra un evento SIF en la tabla ge_sif_event_log</summary>
    procedure RegistrarEvento(AEmpresaId: Integer; ATipoEvento: TSifTipoEvento;
      const ADescripcion: string; const ADatosJson: string = ''; AUserId: Integer = 1);
  end;

implementation

constructor TSifEventLogger.Create(AConnection: TFDConnection);
begin
  inherited Create;
  FConnection := AConnection;
end;

procedure TSifEventLogger.RegistrarEvento(AEmpresaId: Integer; ATipoEvento: TSifTipoEvento;
  const ADescripcion: string; const ADatosJson: string; AUserId: Integer);
var
  LQry: TFDQuery;
begin
  if (FConnection = nil) or not FConnection.Connected then
    Exit;

  LQry := TFDQuery.Create(nil);
  try
    LQry.Connection := FConnection;
    LQry.SQL.Text :=
      'INSERT INTO ge_sif_event_log (empresa_id, tipo_evento, descripcion, datos_adicionales, usuario_id, fecha_hora) ' +
      'VALUES (:EMPRESA, :TIPO, :DESC, :DATOS, :USER, CURRENT_TIMESTAMP(3))';

    LQry.ParamByName('EMPRESA').AsInteger := AEmpresaId;
    LQry.ParamByName('TIPO').AsString := TipoEventoToString(ATipoEvento);
    LQry.ParamByName('DESC').DataType := ftWideString;
    LQry.ParamByName('DESC').AsWideString := ADescripcion;

    if Trim(ADatosJson) <> '' then
    begin
      LQry.ParamByName('DATOS').DataType := ftWideString;
      LQry.ParamByName('DATOS').AsWideString := ADatosJson;
    end
    else
      LQry.ParamByName('DATOS').Clear;

    if AUserId > 0 then
      LQry.ParamByName('USER').AsInteger := AUserId
    else
      LQry.ParamByName('USER').Clear;

    LQry.ExecSQL;
  except
    on E: Exception do
    begin
      // Los errores de log no deben romper el flujo principal, pero se pueden registrar
    end;
  end;
  LQry.Free;
end;

end.
