﻿unit frm_EnviosConfig;

{
  frm_EnviosConfig.pas
  Configuración de acceso a una empresa de transporte (genérico).

  Se abre desde frm_EmpresasEditor con un TransportistaId concreto.
  Permite introducir las credenciales y datos del remitente para
  ese transportista+empresa. El botón "Probar Conexión" usa el Factory
  para verificar que las credenciales son válidas.
}

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, Vcl.Grids, Vcl.DBGrids, Vcl.ComCtrls;

type
  TfrmEnviosConfig = class(TfrmBase)
    // ── Transporte seleccionado (informativo) ────────────────────────────────
    pnlTranspInfo: TPanel;
    lblTranspNombre: TLabel;
    edtTranspNombre: TEdit;

    // ── Credenciales ─────────────────────────────────────────────────────────
    grpCredenciales: TGroupBox;
    lblEntorno: TLabel;
    cbEntorno: TComboBox;
    lblCodAgencia: TLabel;
    edtCodAgencia: TEdit;
    lblCodCliente: TLabel;
    edtCodCliente: TEdit;
    lblPassword: TLabel;
    edtPassword: TEdit;
    chkActivo: TCheckBox;
    pnlTest: TPanel;
    btnTestConexion: TButton;
    lblResultadoTest: TLabel;
    lblUrlProduccion: TLabel;
    edtUrlProduccion: TEdit;
    lblUrlPruebas: TLabel;
    edtUrlPruebas: TEdit;
    lblCodAgenciaVal: TLabel;
    edtCodAgenciaVal: TEdit;
    lblCodClienteVal: TLabel;
    edtCodClienteVal: TEdit;
    lblPasswordVal: TLabel;
    edtPasswordVal: TEdit;

    // ── 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;
    lblEmailRemitente: TLabel;
    edtEmailRemitente: TEdit;

    // ── Servicio por defecto ─────────────────────────────────────────────────
    grpServicio: TGroupBox;
    lblServDefecto: TLabel;
    cbServDefecto: TComboBox;
    lblModeloImpresora: TLabel;
    cbModeloImpresora: TComboBox;

    procedure FormShow(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnSalirClick(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      : Integer;
    FTransportistaId: Integer;
    FConfigId       : Integer;     // 0 = nuevo registro
    FTipoApi        : string;
    FParentForm     : TForm;
    procedure LoadData;
    procedure PopularServicioCombo;
  public
    property EmpresaId      : Integer read FEmpresaId       write FEmpresaId;
    property TransportistaId: Integer read FTransportistaId  write FTransportistaId;
    property ParentForm     : TForm   read FParentForm       write FParentForm;
  end;

var
  frmEnviosConfig: TfrmEnviosConfig;

implementation

uses
  dmg_Main, uDbErrorHandler,
  uEnviosTypes, uEnviosClient;

{$R *.dfm}

procedure TfrmEnviosConfig.PopularServicioCombo;
var
  Qry: TFDQuery;
begin
  cbServDefecto.Items.Clear;
  if FTransportistaId = 0 then Exit;

  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text :=
      'SELECT codigo, descripcion ' +
      'FROM ge_envios_servicios ' +
      'WHERE transportista_id = :transp AND activo = 1 ' +
      'ORDER BY codigo';
    Qry.ParamByName('transp').AsInteger := FTransportistaId;
    Qry.Open;
    while not Qry.Eof do
    begin
      cbServDefecto.Items.Add(Qry.FieldByName('codigo').AsString + ' - ' + Qry.FieldByName('descripcion').AsString);
      Qry.Next;
    end;
  finally
    Qry.Free;
  end;

  if cbServDefecto.Items.Count > 0 then
    cbServDefecto.ItemIndex := 0;
end;

procedure TfrmEnviosConfig.FormShow(Sender: TObject);
var
  Qry: TFDQuery;
begin
  TAppTheme.ApplyToForm(Self);
  btnGuardar.OnClick := btnSaveClick;
  btnSalir.OnClick   := btnSalirClick;

  // Ocultar partes del formulario base que no aplican
  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 (servidor real)');
  cbEntorno.Items.Add('Validación / Pruebas');
  cbEntorno.ItemIndex := 0;

  cbModeloImpresora.Items.Clear;
  cbModeloImpresora.Items.Add('PDF_B - Formato PDF');
  cbModeloImpresora.Items.Add('ZEBRA_B - Impresoras Zebra');
  cbModeloImpresora.Items.Add('TECFV4_B - Toshiba TEC FV4');
  cbModeloImpresora.Items.Add('TECEV4_B - Toshiba TEC EV4');
  cbModeloImpresora.Items.Add('TECSV4_B - Toshiba TEC SV4');
  cbModeloImpresora.Items.Add('IMAGEN_B - Imagen PNG');
  cbModeloImpresora.ItemIndex := 0;

  FConfigId := 0;
  FTipoApi  := '';

  // Cargar nombre e información del transportista seleccionado
  if FTransportistaId > 0 then
  begin
    Qry := TFDQuery.Create(nil);
    try
      Qry.Connection := dmgMain.dbConn;
      Qry.SQL.Text :=
        'SELECT nombre, tipo_api FROM ge_envios_transportistas WHERE id = :id';
      Qry.ParamByName('id').AsInteger := FTransportistaId;
      Qry.Open;
      if not Qry.IsEmpty then
      begin
        edtTranspNombre.Text := Qry.FieldByName('nombre').AsString;
        FTipoApi             := Qry.FieldByName('tipo_api').AsString;
        Caption := 'Config. Envíos — ' + edtTranspNombre.Text;
      end;
    finally
      Qry.Free;
    end;
  end;

  PopularServicioCombo;

  if (FEmpresaId > 0) and (FTransportistaId > 0) then
    LoadData
  else
    DoAnadir;
end;

procedure TfrmEnviosConfig.LoadData;
var
  Qry: TFDQuery;
  LServCode: string;
  i: Integer;
begin
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text   :=
      'SELECT * FROM ge_envios_config ' +
      'WHERE empresa_id = :emp AND transportista_id = :transp LIMIT 1';
    Qry.ParamByName('emp').AsInteger   := FEmpresaId;
    Qry.ParamByName('transp').AsInteger := FTransportistaId;
    Qry.Open;

    if not Qry.IsEmpty then
    begin
      FConfigId := Qry.FieldByName('id').AsInteger;
      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;
      edtCodAgenciaVal.Text  := Qry.FieldByName('cod_agencia_val').AsString;
      edtCodClienteVal.Text  := Qry.FieldByName('cod_cliente_val').AsString;
      edtPasswordVal.Text    := Qry.FieldByName('password_val').AsString;
      chkActivo.Checked      := Qry.FieldByName('activo').AsInteger <> 0;
      edtUrlProduccion.Text  := Qry.FieldByName('url_produccion').AsString;
      edtUrlPruebas.Text     := Qry.FieldByName('url_pruebas').AsString;
      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;
      edtEmailRemitente.Text := Qry.FieldByName('email_remitente').AsString;

      LServCode := Qry.FieldByName('serv_defecto').AsString;
      for i := 0 to cbServDefecto.Items.Count - 1 do
        if cbServDefecto.Items[i].StartsWith(LServCode) then
        begin
          cbServDefecto.ItemIndex := i;
          Break;
        end;

      var LModeloImp := Qry.FieldByName('modelo_impresora').AsString;
      if LModeloImp = '' then LModeloImp := 'PDF_B';
      for i := 0 to cbModeloImpresora.Items.Count - 1 do
        if cbModeloImpresora.Items[i].StartsWith(LModeloImp) then
        begin
          cbModeloImpresora.ItemIndex := i;
          Break;
        end;
    end
    else
      DoAnadir;
  finally
    Qry.Free;
  end;
end;

procedure TfrmEnviosConfig.DoAnadir;
begin
  FConfigId := 0;
  cbEntorno.ItemIndex := 0;
  edtCodAgencia.Clear; edtCodCliente.Clear; edtPassword.Clear;
  edtCodAgenciaVal.Clear; edtCodClienteVal.Clear; edtPasswordVal.Clear;
  edtUrlProduccion.Clear; edtUrlPruebas.Clear;
  edtNomRemitente.Clear; edtDirRemitente.Clear;
  edtPobRemitente.Clear; edtCPRemitente.Clear; edtTlfRemitente.Clear;
  edtEmailRemitente.Clear;
  chkActivo.Checked := True;
  cbServDefecto.ItemIndex := 0;
  cbModeloImpresora.ItemIndex := 0;
  lblResultadoTest.Caption := '';
  edtCodAgencia.SetFocus;
end;

procedure TfrmEnviosConfig.DoModificar;
begin edtCodAgencia.SetFocus; end;
procedure TfrmEnviosConfig.DoPrimero;   begin end;
procedure TfrmEnviosConfig.DoAnterior;  begin end;
procedure TfrmEnviosConfig.DoSiguiente; begin end;
procedure TfrmEnviosConfig.DoUltimo;    begin end;
procedure TfrmEnviosConfig.btnSalirClick(Sender: TObject); begin Close; end;

// ---------------------------------------------------------------------------
procedure TfrmEnviosConfig.btnTestConexionClick(Sender: TObject);
var
  LConfig : TEnviosConfig;
  LClient : IEnviosClient;
  LError  : string;
begin
  if Trim(edtCodAgencia.Text) = '' then begin ShowMessage('Introduzca el código de agencia.'); Exit; end;
  if Trim(edtCodCliente.Text) = '' then begin ShowMessage('Introduzca el código de cliente.'); Exit; end;

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

  // Construir config temporal con los datos del formulario
  LConfig.ConfigId        := 0;
  LConfig.TransportistaId := FTransportistaId;
  LConfig.NombreTransp    := edtTranspNombre.Text;
  LConfig.TipoApi         := FTipoApi;
  LConfig.TipoEnum        := TipoTransportistaFromStr(FTipoApi);
  LConfig.Entorno         := (cbEntorno.ItemIndex = 1);
  if LConfig.Entorno then
  begin
    LConfig.CodAgencia    := Trim(edtCodAgenciaVal.Text);
    LConfig.CodCliente    := Trim(edtCodClienteVal.Text);
    LConfig.Password      := Trim(edtPasswordVal.Text);
  end
  else
  begin
    LConfig.CodAgencia    := Trim(edtCodAgencia.Text);
    LConfig.CodCliente    := Trim(edtCodCliente.Text);
    LConfig.Password      := Trim(edtPassword.Text);
  end;
  LConfig.UrlProduccion   := Trim(edtUrlProduccion.Text);
  LConfig.UrlPruebas      := Trim(edtUrlPruebas.Text);

  LClient := TEnviosClientFactory.Create(LConfig, LError);
  if not Assigned(LClient) then
  begin
    lblResultadoTest.Caption := '❌ ' + LError;
    lblResultadoTest.Font.Color := clRed;
    Exit;
  end;

  try
    try
      if LClient.Login then
      begin
        lblResultadoTest.Caption := '✅ Conexión correcta con ' + edtTranspNombre.Text;
        lblResultadoTest.Font.Color := clGreen;
      end;
    except
      on E: Exception do
      begin
        lblResultadoTest.Caption := '❌ Error: ' + E.Message;
        lblResultadoTest.Font.Color := clRed;
      end;
    end;
  finally
    LClient := nil;
  end;
end;

procedure TfrmEnviosConfig.btnSaveClick(Sender: TObject);
var
  LServCode, LModeloImpCode: string;
begin
  if Trim(edtCodAgencia.Text) = '' then begin ShowMessage('El código de agencia es obligatorio.'); Exit; end;
  if FEmpresaId = 0  then begin ShowMessage('No se especificó empresa.'); Exit; end;
  if FTransportistaId = 0 then begin ShowMessage('No se especificó transportista.'); Exit; end;

  if cbServDefecto.ItemIndex >= 0 then
    LServCode := Copy(cbServDefecto.Items[cbServDefecto.ItemIndex], 1, 2)
  else
    LServCode := '48';

  if cbModeloImpresora.ItemIndex >= 0 then
    LModeloImpCode := cbModeloImpresora.Items[cbModeloImpresora.ItemIndex].Split([' - '])[0]
  else
    LModeloImpCode := 'PDF_B';

  try
    dmgMain.qryExec.Close;
    if FConfigId = 0 then
      dmgMain.qryExec.SQL.Text :=
        'INSERT INTO ge_envios_config ' +
        '(empresa_id, transportista_id, activo, entorno, cod_agencia, cod_cliente, password,' +
        ' cod_agencia_val, cod_cliente_val, password_val,' +
        ' nom_remitente, dir_remitente, pob_remitente, cp_remitente, tlf_remitente, email_remitente, modelo_impresora,' +
        ' serv_defecto, url_produccion, url_pruebas, id_user_creator, id_user_update) ' +
        'VALUES (:emp, :transp, :act, :ent, :age, :cli, :pwd,' +
        '        :age_val, :cli_val, :pwd_val,' +
        '        :nomrem, :dirrem, :pobrem, :cprem, :tlfrem, :emailrem, :modelo_imp,' +
        '        :serv, :url_prod, :url_pruebas, :user, :user)'
    else
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_envios_config SET activo=:act, entorno=:ent,' +
        ' cod_agencia=:age, cod_cliente=:cli, password=:pwd,' +
        ' cod_agencia_val=:age_val, cod_cliente_val=:cli_val, password_val=:pwd_val,' +
        ' nom_remitente=:nomrem, dir_remitente=:dirrem, pob_remitente=:pobrem,' +
        ' cp_remitente=:cprem, tlf_remitente=:tlfrem, email_remitente=:emailrem, modelo_impresora=:modelo_imp,' +
        ' serv_defecto=:serv, url_produccion=:url_prod, url_pruebas=:url_pruebas, ' +
        ' id_user_update=:user, updated_at=CURRENT_TIMESTAMP' +
        ' WHERE id=:id';

    if FConfigId = 0 then
    begin
      dmgMain.qryExec.ParamByName('emp').AsInteger   := FEmpresaId;
      dmgMain.qryExec.ParamByName('transp').AsInteger := FTransportistaId;
    end
    else
      dmgMain.qryExec.ParamByName('id').AsInteger := FConfigId;

    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('age_val').DataType    := ftWideString;
    dmgMain.qryExec.ParamByName('age_val').Value       := Trim(edtCodAgenciaVal.Text);
    dmgMain.qryExec.ParamByName('cli_val').DataType    := ftWideString;
    dmgMain.qryExec.ParamByName('cli_val').Value       := Trim(edtCodClienteVal.Text);
    dmgMain.qryExec.ParamByName('pwd_val').DataType    := ftWideString;
    dmgMain.qryExec.ParamByName('pwd_val').Value       := Trim(edtPasswordVal.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('emailrem').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('emailrem').Value  := Trim(edtEmailRemitente.Text);
    dmgMain.qryExec.ParamByName('modelo_imp').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('modelo_imp').Value := LModeloImpCode;
    dmgMain.qryExec.ParamByName('serv').DataType   := ftWideString;
    dmgMain.qryExec.ParamByName('serv').Value      := LServCode;
    dmgMain.qryExec.ParamByName('url_prod').DataType    := ftWideString;
    dmgMain.qryExec.ParamByName('url_prod').Value       := Trim(edtUrlProduccion.Text);
    dmgMain.qryExec.ParamByName('url_pruebas').DataType := ftWideString;
    dmgMain.qryExec.ParamByName('url_pruebas').Value    := Trim(edtUrlPruebas.Text);
    dmgMain.qryExec.ParamByName('user').AsString   := dmgMain.CurrentUserId;

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

end.
