unit uEnviarDocumento;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, FireDAC.Comp.Client, Data.DB;

type
  TEmailProfileItem = class
  public
    Id: string;
    NombrePerfil: string;
    constructor Create(const AId, ANombre: string);
  end;

  TfEnviarDocumento = class(TForm)
    pnlBottom: TPanel;
    btnEnviar: TButton;
    btnCancelar: TButton;
    GroupBox1: TGroupBox;
    chkEmail: TCheckBox;
    Label1: TLabel;
    edtEmailDestino: TEdit;
    Label2: TLabel;
    edtEmailAsunto: TEdit;
    Label3: TLabel;
    mmoEmailMensaje: TMemo;
    lblAdjunto: TLabel;
    btnVerPDF: TButton;
    btnConfigurar: TButton;
    pnlTop: TPanel;
    Label6: TLabel;
    cboCuentasEnvio: TComboBox;
    Label4: TLabel;
    edtEmailCopia: TEdit;
    procedure cboCuentasEnvioChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure chkEmailClick(Sender: TObject);
    procedure chkWhatsAppClick(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
    procedure btnEnviarClick(Sender: TObject);
    procedure btnVerPDFClick(Sender: TObject);
    procedure btnConfigurarClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    FRutasPDF: TArray<string>;
    procedure ConfigurarUI;
    procedure CargarCuentas;
    procedure ActualizarEtiquetaAdjuntos;
    function GetRutaPDF: string;
    procedure SetRutaPDF(const Value: string);
    procedure SetRutasPDF(const Values: TArray<string>);
  public
    { Public declarations }
    destructor Destroy; override;
    property RutasPDF: TArray<string> read FRutasPDF write SetRutasPDF;
    property RutaPDF: string read GetRutaPDF write SetRutaPDF;
    procedure InitData(const ATelefono, AEmail, ACCO, AAsuntoDefault: string; const AReportName: string);
  end;

var
  fEnviarDocumento: TfEnviarDocumento;

implementation

{$R *.dfm}

uses uEmailWhatsApp, Winapi.ShellAPI, frm_ConfigEnvio, frm_ConfigEnvioEditor, dmg_Main, System.UITypes;

{ TEmailProfileItem }

constructor TEmailProfileItem.Create(const AId, ANombre: string);
begin
  Id := AId;
  NombrePerfil := ANombre;
end;

{ TfEnviarDocumento }

destructor TfEnviarDocumento.Destroy;
var
  Idx: Integer;
begin
  for Idx := 0 to cboCuentasEnvio.Items.Count - 1 do
    if cboCuentasEnvio.Items.Objects[Idx] <> nil then
      cboCuentasEnvio.Items.Objects[Idx].Free;
  inherited Destroy;
end;

procedure TfEnviarDocumento.FormCreate(Sender: TObject);
begin
  CargarCuentas;
  ConfigurarUI;
end;

procedure TfEnviarDocumento.FormShow(Sender: TObject);
var
  SelID: string;
  SmtpHost, SmtpUsuario, SmtpPassword, SmtpNombre: string;
  SmtpPuerto, WaModo: Integer;
  SmtpSSL: Boolean;
  WaTelefono, WaApiKey, TplEmailAsunto, TplEmailCuerpo, TplWaMensaje, FirmaHTML: string;
begin
  if cboCuentasEnvio.ItemIndex = -1 then Exit;
  SelID := TEmailProfileItem(cboCuentasEnvio.Items.Objects[cboCuentasEnvio.ItemIndex]).Id;

  // Recargar plantillas según la cuenta elegida
  LeerConfiguracion(SelID, SmtpHost, SmtpPuerto, SmtpSSL, SmtpUsuario, SmtpPassword, SmtpNombre,
    WaModo, WaTelefono, WaApiKey, TplEmailAsunto, TplEmailCuerpo, TplWaMensaje, FirmaHTML);
  edtEmailCopia.Text := SmtpUsuario;
end;

procedure TfEnviarDocumento.CargarCuentas;
var
  Qry: TFDQuery;
  Idx: Integer;
begin
  // Limpiar cuentas anteriores
  for Idx := 0 to cboCuentasEnvio.Items.Count - 1 do
    if cboCuentasEnvio.Items.Objects[Idx] <> nil then
      cboCuentasEnvio.Items.Objects[Idx].Free;
  cboCuentasEnvio.Items.Clear;

  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text := 'SELECT id, nombre_perfil FROM ge_config_envio ORDER BY nombre_perfil';
    Qry.Open;
    while not Qry.Eof do
    begin
      cboCuentasEnvio.Items.AddObject(Qry.FieldByName('nombre_perfil').AsString, 
        TEmailProfileItem.Create(Qry.FieldByName('id').AsString, Qry.FieldByName('nombre_perfil').AsString));
      Qry.Next;
    end;
  finally
    Qry.Free;
  end;

  if cboCuentasEnvio.Items.Count > 0 then
  begin
    cboCuentasEnvio.ItemIndex := 0;
    cboCuentasEnvioChange(Self);
  end;
end;

function TfEnviarDocumento.GetRutaPDF: string;
begin
  if Length(FRutasPDF) > 0 then
    Result := FRutasPDF[0]
  else
    Result := '';
end;

procedure TfEnviarDocumento.SetRutaPDF(const Value: string);
begin
  if Trim(Value) <> '' then
    SetRutasPDF([Value])
  else
    SetRutasPDF([]);
end;

procedure TfEnviarDocumento.SetRutasPDF(const Values: TArray<string>);
begin
  FRutasPDF := Values;
  ActualizarEtiquetaAdjuntos;
end;

procedure TfEnviarDocumento.ActualizarEtiquetaAdjuntos;
var
  Idx: Integer;
  LList: string;
  LSummary: string;
begin
  if Length(FRutasPDF) = 0 then
  begin
    lblAdjunto.Caption := 'Sin archivos adjuntos';
    lblAdjunto.Hint := '';
    lblAdjunto.ShowHint := False;
    btnVerPDF.Enabled := False;
  end
  else if Length(FRutasPDF) = 1 then
  begin
    lblAdjunto.Caption := 'Adjunto: ' + ExtractFileName(FRutasPDF[0]);
    lblAdjunto.Hint := FRutasPDF[0];
    lblAdjunto.ShowHint := True;
    btnVerPDF.Enabled := True;
  end
  else
  begin
    LSummary := Format('Adjuntos (%d): ', [Length(FRutasPDF)]);
    LList := '';
    for Idx := 0 to High(FRutasPDF) do
    begin
      if Idx < 2 then
      begin
        if Idx > 0 then LSummary := LSummary + ', ';
        LSummary := LSummary + ExtractFileName(FRutasPDF[Idx]);
      end;
      if LList <> '' then LList := LList + sLineBreak;
      LList := LList + ExtractFileName(FRutasPDF[Idx]) + ' (' + FRutasPDF[Idx] + ')';
    end;
    if Length(FRutasPDF) > 2 then
      LSummary := LSummary + Format(' y %d más...', [Length(FRutasPDF) - 2]);

    lblAdjunto.Caption := LSummary;
    lblAdjunto.Hint := LList;
    lblAdjunto.ShowHint := True;
    btnVerPDF.Enabled := True;
  end;
end;

procedure TfEnviarDocumento.InitData(const ATelefono, AEmail, ACCO, AAsuntoDefault: string; const AReportName: string);
begin
  edtEmailDestino.Text := AEmail;
  edtEmailCopia.Text := ACCO;
  if AAsuntoDefault <> '' then
  begin
    // Reemplazar la variable {documento} en el asunto
    edtEmailAsunto.Text := StringReplace(edtEmailAsunto.Text, '{documento}', AAsuntoDefault, [rfReplaceAll, rfIgnoreCase]);
  end;

  if Trim(AEmail) <> '' then chkEmail.Checked := True;
  
  ActualizarEtiquetaAdjuntos;
  ConfigurarUI;
end;

procedure TfEnviarDocumento.ConfigurarUI;
begin
  edtEmailDestino.Enabled := chkEmail.Checked;
  edtEmailCopia.Enabled := chkEmail.Checked;
  edtEmailAsunto.Enabled := chkEmail.Checked;
  mmoEmailMensaje.Enabled := chkEmail.Checked;
  btnEnviar.Enabled := chkEmail.Checked;
end;

procedure TfEnviarDocumento.chkEmailClick(Sender: TObject);
begin
  ConfigurarUI;
end;

procedure TfEnviarDocumento.chkWhatsAppClick(Sender: TObject);
begin
  ConfigurarUI;
end;

procedure TfEnviarDocumento.btnCancelarClick(Sender: TObject);
begin
  Close;
end;

procedure TfEnviarDocumento.btnVerPDFClick(Sender: TObject);
var
  Idx: Integer;
begin
  if Length(FRutasPDF) = 0 then
  begin
    MessageDlg('No hay archivos PDF adjuntos para visualizar.', mtWarning, [mbOK], 0);
    Exit;
  end;

  if Length(FRutasPDF) = 1 then
  begin
    if FileExists(FRutasPDF[0]) then
      ShellExecute(0, 'open', PChar(FRutasPDF[0]), nil, nil, SW_SHOWNORMAL)
    else
      MessageDlg('El archivo PDF no se ha encontrado:' + sLineBreak + FRutasPDF[0], mtError, [mbOK], 0);
  end
  else
  begin
    // Si hay varios archivos, abrimos la carpeta donde se han generado
    if FileExists(FRutasPDF[0]) then
      ShellExecute(0, 'open', PChar(ExtractFilePath(FRutasPDF[0])), nil, nil, SW_SHOWNORMAL)
    else
    begin
      for Idx := 0 to High(FRutasPDF) do
        if FileExists(FRutasPDF[Idx]) then
          ShellExecute(0, 'open', PChar(FRutasPDF[Idx]), nil, nil, SW_SHOWNORMAL);
    end;
  end;
end;

procedure TfEnviarDocumento.btnEnviarClick(Sender: TObject);
var
  LErrorMsg: string;
  LEnvioEmailOk: Boolean;
  LTotalMensaje: string;
  LSelConfigID: string;
  LFile: string;
begin
  LEnvioEmailOk := False;
  LTotalMensaje := '';
  
  if cboCuentasEnvio.ItemIndex = -1 then
  begin
    MessageDlg('Debe seleccionar una cuenta de envío.', mtError, [mbOK], 0);
    Exit;
  end;
  
  LSelConfigID := TEmailProfileItem(cboCuentasEnvio.Items.Objects[cboCuentasEnvio.ItemIndex]).Id;

  if Length(FRutasPDF) = 0 then
  begin
    MessageDlg('No hay ningún archivo PDF adjunto para enviar.', mtError, [mbOK], 0);
    Exit;
  end;

  for LFile in FRutasPDF do
  begin
    if not FileExists(LFile) then
    begin
      MessageDlg('El archivo adjunto no existe:' + sLineBreak + LFile, mtError, [mbOK], 0);
      Exit;
    end;
  end;

  // 1. Enviar Email si está marcado
  if chkEmail.Checked and ((Trim(edtEmailDestino.Text) <> '') or (Trim(edtEmailCopia.Text) <> '')) then
  begin
    Screen.Cursor := crHourGlass;
    try
      if EnviarEmail(LSelConfigID, Trim(edtEmailDestino.Text), edtEmailAsunto.Text, mmoEmailMensaje.Text, FRutasPDF, Trim(edtEmailCopia.Text), LErrorMsg) then
      begin
        LEnvioEmailOk := True;
        if Length(FRutasPDF) > 1 then
          LTotalMensaje := LTotalMensaje + Format('Email enviado correctamente con %d archivos adjuntos.' + #13#10, [Length(FRutasPDF)])
        else
          LTotalMensaje := LTotalMensaje + 'Email enviado correctamente.' + #13#10;
      end
      else
        LTotalMensaje := LTotalMensaje + 'Fallo al enviar email: ' + LErrorMsg + #13#10;
    finally
      Screen.Cursor := crDefault;
    end;
  end;

  if LTotalMensaje = '' then LTotalMensaje := 'Operación finalizada.';
  MessageDlg(LTotalMensaje, mtInformation, [mbOK], 0);
  ModalResult := mrOk;
end;

procedure TfEnviarDocumento.btnConfigurarClick(Sender: TObject);
var
  LId: Integer;
begin
  LId := 0;
  if cboCuentasEnvio.ItemIndex >= 0 then
    LId := StrToIntDef(TEmailProfileItem(cboCuentasEnvio.Items.Objects[cboCuentasEnvio.ItemIndex]).Id, 0);

  if not Assigned(frmConfigEnvioEditor) then
    Application.CreateForm(TfrmConfigEnvioEditor, frmConfigEnvioEditor);

  frmConfigEnvioEditor.ParentForm := Self;
  frmConfigEnvioEditor.ConfigEnvioId := LId;
  frmConfigEnvioEditor.ShowModal;
  CargarCuentas;
end;

procedure TfEnviarDocumento.cboCuentasEnvioChange(Sender: TObject);
var
  SelID: string;
  SmtpHost, SmtpUsuario, SmtpPassword, SmtpNombre: string;
  SmtpPuerto, WaModo: Integer;
  SmtpSSL: Boolean;
  WaTelefono, WaApiKey, TplEmailAsunto, TplEmailCuerpo, TplWaMensaje, FirmaHTML: string;
begin
  if cboCuentasEnvio.ItemIndex = -1 then Exit;
  SelID := TEmailProfileItem(cboCuentasEnvio.Items.Objects[cboCuentasEnvio.ItemIndex]).Id;

  // Recargar plantillas según la cuenta elegida
  LeerConfiguracion(SelID, SmtpHost, SmtpPuerto, SmtpSSL, SmtpUsuario, SmtpPassword, SmtpNombre,
    WaModo, WaTelefono, WaApiKey, TplEmailAsunto, TplEmailCuerpo, TplWaMensaje, FirmaHTML);
      
    edtEmailAsunto.Text := TplEmailAsunto;
    mmoEmailMensaje.Text := TplEmailCuerpo;

  if (edtEmailCopia.Text = '') or (Pos(';', edtEmailCopia.Text) = 0) then
    edtEmailCopia.Text := SmtpUsuario
  else
  begin
    edtEmailCopia.Text := SmtpUsuario + ';' + Copy(edtEmailCopia.Text, Pos(';', edtEmailCopia.Text) + 1, MaxInt);
  end;
end;

end.
