﻿unit frm_TipsaConfig;

{
  frm_TipsaConfig.pas
  Formulario de configuración del acceso al API TIPSA por empresa.

  Permite al usuario introducir y verificar las credenciales TIPSA:
    - Código de agencia, código de cliente y contraseña
    - Entorno (Producción / Validación)
    - Datos del remitente (empresa) estructurados para el API
    - Tipo de servicio por defecto
  Incluye un botón "Probar Conexión" que ejecuta el Login contra TIPSA
  y muestra el resultado inmediatamente.
}

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Buttons, Data.DB, FireDAC.Comp.Client,
  FireDAC.Stan.Param, uAppTheme, uBaseForm;

type
  TfrmTipsaConfig = class(TfrmBase)
    // ── Credenciales ────────────────────────────────────────────
    grpCredenciales: TGroupBox;
    lblEntorno: TLabel;
    cbEntorno: TComboBox;
    lblCodAgencia: TLabel;
    edtCodAgencia: TEdit;
    lblCodCliente: TLabel;
    edtCodCliente: TEdit;
    lblPassword: TLabel;
    edtPassword: TEdit;
    chkActivo: TCheckBox;

    // ── Datos del Remitente ──────────────────────────────────────
    grpRemitente: TGroupBox;
    lblNomRemitente: TLabel;
    edtNomRemitente: TEdit;
    lblDirRemitente: TLabel;
    edtDirRemitente: TEdit;
    lblPobRemitente: TLabel;
    edtPobRemitente: TEdit;
    lblCPRemitente: TLabel;
    edtCPRemitente: TEdit;
    lblTlfRemitente: TLabel;
    edtTlfRemitente: TEdit;

    // ── Configuración de Servicio ────────────────────────────────
    grpServicio: TGroupBox;
    lblServDefecto: TLabel;
    cbServDefecto: TComboBox;

    // ── Test de Conexión ─────────────────────────────────────────
    pnlTest: TPanel;
    btnTestConexion: TButton;
    lblResultadoTest: TLabel;

    procedure FormShow(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnSalirClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnTestConexionClick(Sender: TObject);
  protected
    procedure DoAnadir; override;
    procedure DoModificar; override;
    procedure DoPrimero; override;
    procedure DoAnterior; override;
    procedure DoSiguiente; override;
    procedure DoUltimo; override;
  private
    FEmpresaId: string;
    FConfigId: string;
    FParentForm: TForm;
    procedure LoadData;
    procedure PopulateServicioCombo;
  public
    property EmpresaId: string read FEmpresaId write FEmpresaId;
    property ParentForm: TForm read FParentForm write FParentForm;
  end;

var
  frmTipsaConfig: TfrmTipsaConfig;

implementation

uses
  dmg_Main, uDbErrorHandler, uTipsaClient, uTipsaTypes;

{$R *.dfm}

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.PopulateServicioCombo;
begin
  cbServDefecto.Items.Clear;
  cbServDefecto.Items.AddObject('48 - ECONOMY',          TObject(48));
  cbServDefecto.Items.AddObject('19 - EXPRESS 19H',      TObject(19));
  cbServDefecto.Items.AddObject('10 - 10 HORAS',         TObject(10));
  cbServDefecto.Items.AddObject('14 - 14 HORAS',         TObject(14));
  cbServDefecto.Items.AddObject('90 - INT-EXPRESS',      TObject(90));
  cbServDefecto.Items.AddObject('91 - INT-ECONOMY',      TObject(91));
  cbServDefecto.ItemIndex := 0;
end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.FormShow(Sender: TObject);
begin
  TAppTheme.ApplyToForm(Self);

  btnGuardar.OnClick := btnSaveClick;
  btnSalir.OnClick   := btnSalirClick;

  // Ocultar elementos heredados que no aplican a este formulario simple
  pgcDetails.Visible      := True;
  TsListado.TabVisible    := False;
  pgcDetails.ActivePage   := tsDatosEnvio;
  pnlSideToolbar.Visible  := False;
  dbgItems.Visible        := False;
  pnlFooter.Visible       := False;
  btnAnadir.Visible       := False;
  btnEliminar.Visible     := False;
  btnPrimero.Visible      := False;
  btnAnterior.Visible     := False;
  btnSiguiente.Visible    := False;
  btnUltimo.Visible       := False;
  btnModificar.Visible    := False;
  btnBuscar.Visible       := False;
  btnImprimir.Visible     := False;
  btnIA.Visible           := False;
  btnDuplicar.Visible     := False;
  btnRect.Visible         := False;
  btnCancelar.Visible     := False;

  cbEntorno.Items.Clear;
  cbEntorno.Items.Add('Producción (ws.tipsa-dinapaq.com)');
  cbEntorno.Items.Add('Validación / Pruebas (wsval.tipsa-dinapaq.com)');
  cbEntorno.ItemIndex := 0;

  PopulateServicioCombo;

  FConfigId := '';
  if FEmpresaId <> '' then
    LoadData
  else
    DoAnadir;
end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.LoadData;
var
  Qry: TFDQuery;
  LServCode: string;
  i: Integer;
begin
  if FEmpresaId = '' then Exit;

  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text   := 'SELECT * FROM ge_tipsa_config WHERE empresa_id = :emp LIMIT 1';
    Qry.ParamByName('emp').AsString := FEmpresaId;
    Qry.Open;

    if not Qry.IsEmpty then
    begin
      FConfigId := Qry.FieldByName('id').AsString;

      if Qry.FieldByName('entorno').AsInteger <> 0 then
        cbEntorno.ItemIndex := 1
      else
        cbEntorno.ItemIndex := 0;
      edtCodAgencia.Text     := Qry.FieldByName('cod_agencia').AsString;
      edtCodCliente.Text     := Qry.FieldByName('cod_cliente').AsString;
      edtPassword.Text       := Qry.FieldByName('password').AsString;
      chkActivo.Checked      := Qry.FieldByName('activo').AsInteger <> 0;
      edtNomRemitente.Text   := Qry.FieldByName('nom_remitente').AsString;
      edtDirRemitente.Text   := Qry.FieldByName('dir_remitente').AsString;
      edtPobRemitente.Text   := Qry.FieldByName('pob_remitente').AsString;
      edtCPRemitente.Text    := Qry.FieldByName('cp_remitente').AsString;
      edtTlfRemitente.Text   := Qry.FieldByName('tlf_remitente').AsString;

      // Seleccionar el tipo de servicio en el combo
      LServCode := Qry.FieldByName('serv_defecto').AsString;
      for i := 0 to cbServDefecto.Items.Count - 1 do
      begin
        if cbServDefecto.Items[i].StartsWith(LServCode) then
        begin
          cbServDefecto.ItemIndex := i;
          Break;
        end;
      end;
    end
    else
      DoAnadir;
  finally
    Qry.Free;
  end;
end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.DoAnadir;
begin
  FConfigId          := '';
  cbEntorno.ItemIndex := 0;
  edtCodAgencia.Clear;
  edtCodCliente.Clear;
  edtPassword.Clear;
  edtNomRemitente.Clear;
  edtDirRemitente.Clear;
  edtPobRemitente.Clear;
  edtCPRemitente.Clear;
  edtTlfRemitente.Clear;
  chkActivo.Checked  := True;
  cbServDefecto.ItemIndex := 0;
  lblResultadoTest.Caption := '';
  edtCodAgencia.SetFocus;
end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.DoModificar;
begin
  edtCodAgencia.SetFocus;
end;

procedure TfrmTipsaConfig.DoPrimero; begin end;
procedure TfrmTipsaConfig.DoAnterior; begin end;
procedure TfrmTipsaConfig.DoSiguiente; begin end;
procedure TfrmTipsaConfig.DoUltimo; begin end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.FormDestroy(Sender: TObject);
begin
  // No-op
end;

// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.btnSalirClick(Sender: TObject);
begin
  Close;
end;

// ---------------------------------------------------------------------------
// Probar la conexión con TIPSA usando las credenciales del formulario
// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.btnTestConexionClick(Sender: TObject);
var
  LClient   : TTipsaClient;
  LValidacion: Boolean;
begin
  if Trim(edtCodAgencia.Text) = '' then
  begin
    ShowMessage('Introduzca el código de agencia TIPSA.');
    edtCodAgencia.SetFocus;
    Exit;
  end;
  if Trim(edtCodCliente.Text) = '' then
  begin
    ShowMessage('Introduzca el código de cliente TIPSA.');
    edtCodCliente.SetFocus;
    Exit;
  end;

  lblResultadoTest.Caption := '⏳ Conectando con TIPSA...';
  lblResultadoTest.Font.Color := clGray;
  Application.ProcessMessages;

  LValidacion := (cbEntorno.ItemIndex = 1);
  LClient := TTipsaClient.Create(
    Trim(edtCodAgencia.Text),
    Trim(edtCodCliente.Text),
    Trim(edtPassword.Text),
    LValidacion);
  try
    try
      if LClient.Login then
      begin
        lblResultadoTest.Caption :=
          '✅ Conexión correcta. Sesión: ' + Copy(LClient.SessionGUID, 1, 20) + '...';
        lblResultadoTest.Font.Color := clGreen;
      end
      else
      begin
        lblResultadoTest.Caption := '❌ Login fallido. Verifique las credenciales.';
        lblResultadoTest.Font.Color := clRed;
      end;
    except
      on E: Exception do
      begin
        lblResultadoTest.Caption := '❌ Error: ' + E.Message;
        lblResultadoTest.Font.Color := clRed;
      end;
    end;
  finally
    LClient.Free;
  end;
end;

// ---------------------------------------------------------------------------
// Guardar la configuración en ge_tipsa_config
// ---------------------------------------------------------------------------
procedure TfrmTipsaConfig.btnSaveClick(Sender: TObject);
var
  LServCode: string;
begin
  if Trim(edtCodAgencia.Text) = '' then
  begin
    ShowMessage('El código de agencia es obligatorio.');
    edtCodAgencia.SetFocus;
    Exit;
  end;
  if FEmpresaId = '' then
  begin
    ShowMessage('No se ha especificado una empresa.');
    Exit;
  end;

  // Extraer código de servicio del combo (primeros 2 caracteres)
  if cbServDefecto.ItemIndex >= 0 then
    LServCode := Copy(cbServDefecto.Items[cbServDefecto.ItemIndex], 1, 2)
  else
    LServCode := '48';

  try
    dmgMain.qryExec.Close;
    if FConfigId = '' then
    begin
      // INSERT
      dmgMain.qryExec.SQL.Text :=
        'INSERT INTO ge_tipsa_config ' +
        '(empresa_id, activo, entorno, cod_agencia, cod_cliente, password, ' +
        ' nom_remitente, dir_remitente, pob_remitente, cp_remitente, tlf_remitente, ' +
        ' serv_defecto, id_user_creator, id_user_update) ' +
        'VALUES (:emp, :act, :ent, :age, :cli, :pwd, ' +
        '        :nomrem, :dirrem, :pobrem, :cprem, :tlfrem, ' +
        '        :serv, :user, :user)';
    end
    else
    begin
      // UPDATE
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_tipsa_config SET ' +
        'activo = :act, entorno = :ent, cod_agencia = :age, cod_cliente = :cli, ' +
        'password = :pwd, nom_remitente = :nomrem, dir_remitente = :dirrem, ' +
        'pob_remitente = :pobrem, cp_remitente = :cprem, tlf_remitente = :tlfrem, ' +
        'serv_defecto = :serv, id_user_update = :user, ' +
        'updated_at = CURRENT_TIMESTAMP ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id').AsString := FConfigId;
    end;

    if FConfigId = '' then
      dmgMain.qryExec.ParamByName('emp').AsString := FEmpresaId;

    dmgMain.qryExec.ParamByName('act').AsBoolean := chkActivo.Checked;
    dmgMain.qryExec.ParamByName('ent').AsInteger := cbEntorno.ItemIndex;
    dmgMain.qryExec.ParamByName('age').DataType  := ftWideString;
    dmgMain.qryExec.ParamByName('age').Value     := Trim(edtCodAgencia.Text);
    dmgMain.qryExec.ParamByName('cli').DataType  := ftWideString;
    dmgMain.qryExec.ParamByName('cli').Value     := Trim(edtCodCliente.Text);
    dmgMain.qryExec.ParamByName('pwd').DataType  := ftWideString;
    dmgMain.qryExec.ParamByName('pwd').Value     := Trim(edtPassword.Text);
    dmgMain.qryExec.ParamByName('nomrem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('nomrem').Value  := Trim(edtNomRemitente.Text);
    dmgMain.qryExec.ParamByName('dirrem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('dirrem').Value  := Trim(edtDirRemitente.Text);
    dmgMain.qryExec.ParamByName('pobrem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('pobrem').Value  := Trim(edtPobRemitente.Text);
    dmgMain.qryExec.ParamByName('cprem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('cprem').Value   := Trim(edtCPRemitente.Text);
    dmgMain.qryExec.ParamByName('tlfrem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('tlfrem').Value  := Trim(edtTlfRemitente.Text);
    dmgMain.qryExec.ParamByName('serv').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('serv').Value    := LServCode;
    dmgMain.qryExec.ParamByName('user').AsString := dmgMain.CurrentUserId;

    dmgMain.qryExec.ExecSQL;
    ShowMessage('✅ Configuración TIPSA guardada correctamente.');
    ModalResult := mrOk;
  except
    on E: Exception do
      TDbErrorHandler.HandleException(E, 'Error al guardar la configuración TIPSA');
  end;
end;

end.
