unit uConfig;

interface

uses
  System.SysUtils, System.IniFiles, Vcl.Forms, System.Classes, System.NetEncoding, System.IOUtils;

type
  TAppConfig = record
    // Database
    DBServer: string;
    DBName: string;
    DBUser: string;
    DBPass: string;
    DBPort: Integer;
    
    // Paths
    PathRecepcion: string;
    PathAlbaranes: string;
    PathFacturas: string;
    PathTrabajadores: string;
    PathErrores: string;
    
    // App
    IdEmpresa: string;
    IAModelo: string;
    ApiKey: string;
    
    // Notifications
    EmailErrorDestino: string;
    IdConfigEnvioError: string;
  end;

  TConfigHelper = class
  private
    const CRYPTO_KEY = 127; // Simple XOR key
    class function GetConfigPath: string;
    class function EncryptText(const AText: string): string;
    class function DecryptText(const AText: string): string;
  public
    class function LoadConfig: TAppConfig;
    class procedure SaveConfig(const AConfig: TAppConfig);
    class procedure SaveDefaultConfig;
  end;

var
  Config: TAppConfig;

implementation

{ TConfigHelper }

class function TConfigHelper.GetConfigPath: string;
begin
  Result := ExtractFilePath(Application.ExeName) + 'gestiondoc.ini';
end;

class function TConfigHelper.EncryptText(const AText: string): string;
var
  I: Integer;
  Bytes: TBytes;
begin
  Bytes := TEncoding.UTF8.GetBytes(AText);
  for I := 0 to High(Bytes) do
    Bytes[I] := Bytes[I] xor CRYPTO_KEY;
  Result := 'AGRDOC:' + TNetEncoding.Base64.EncodeBytesToString(Bytes).Replace(#13, '').Replace(#10, '');
end;

class function TConfigHelper.DecryptText(const AText: string): string;
var
  I: Integer;
  Bytes: TBytes;
  EncText: string;
begin
  if not AText.StartsWith('AGRDOC:') then
    Exit(AText);
    
  EncText := AText.Substring(7); // Quitar 'AGRDOC:'
  try
    Bytes := TNetEncoding.Base64.DecodeStringToBytes(EncText);
    for I := 0 to High(Bytes) do
      Bytes[I] := Bytes[I] xor CRYPTO_KEY;
    Result := TEncoding.UTF8.GetString(Bytes);
  except
    Result := AText; 
  end;
end;

class function TConfigHelper.LoadConfig: TAppConfig;
var
  Ini: TMemIniFile;
  Content: string;
  SL: TStringList;
begin
  if not FileExists(GetConfigPath) then
  begin
    SaveDefaultConfig;
  end;

  SL := TStringList.Create;
  try
    try
      SL.LoadFromFile(GetConfigPath, TEncoding.UTF8);
      Content := SL.Text;
    except
      Content := '';
    end;
    
    if Content.StartsWith('AGRDOC:') then
      Content := DecryptText(Content);

    Ini := TMemIniFile.Create('');
    try
      SL.Text := Content;
      Ini.SetStrings(SL);
      
      with Result do
      begin
        DBServer := Ini.ReadString('Database', 'Server', '127.0.0.1');
        DBName   := Ini.ReadString('Database', 'Database', 'agrigest');
        DBUser   := Ini.ReadString('Database', 'User', 'asesoft');
        DBPass   := Ini.ReadString('Database', 'Password', 'Pantera1');
        DBPort   := Ini.ReadInteger('Database', 'Port', 3306);
        
        PathRecepcion    := Ini.ReadString('Paths', 'Recepcion', 'c:\agrigest\documentando');
        PathAlbaranes    := Ini.ReadString('Paths', 'Albaranes', 'c:\agrigest\documentando\Albaranes');
        PathFacturas     := Ini.ReadString('Paths', 'Facturas', 'c:\agrigest\documentando\Facturas');
        PathTrabajadores := Ini.ReadString('Paths', 'Trabajadores', 'c:\agrigest\documentando\Trabajadores');
        PathErrores     := Ini.ReadString('Paths', 'Errores', 'c:\agrigest\documentando\Errores');
        
        IdEmpresa := Ini.ReadString('App', 'IdEmpresa', '1');
        IAModelo  := Ini.ReadString('App', 'IAModelo', 'gemini-1.5-flash');
        ApiKey    := Ini.ReadString('App', 'ApiKey', '');
        
        EmailErrorDestino := Ini.ReadString('Notifications', 'EmailErrorDestino', '');
        IdConfigEnvioError := Ini.ReadString('Notifications', 'IdConfigEnvioError', '');
      end;
    finally
      Ini.Free;
    end;
  finally
    SL.Free;
  end;
end;

class procedure TConfigHelper.SaveConfig(const AConfig: TAppConfig);
var
  Ini: TMemIniFile;
  SL: TStringList;
  S: string;
begin
  // Usamos un TMemIniFile temporal para generar el formato INI
  Ini := TMemIniFile.Create('');
  try
    Ini.WriteString('Database', 'Server', AConfig.DBServer);
    Ini.WriteString('Database', 'Database', AConfig.DBName);
    Ini.WriteString('Database', 'User', AConfig.DBUser);
    Ini.WriteString('Database', 'Password', AConfig.DBPass);
    Ini.WriteInteger('Database', 'Port', AConfig.DBPort);
    
    Ini.WriteString('Paths', 'Recepcion', AConfig.PathRecepcion);
    Ini.WriteString('Paths', 'Albaranes', AConfig.PathAlbaranes);
    Ini.WriteString('Paths', 'Facturas', AConfig.PathFacturas);
    Ini.WriteString('Paths', 'Trabajadores', AConfig.PathTrabajadores);
    Ini.WriteString('Paths', 'Errores', AConfig.PathErrores);
    
    Ini.WriteString('App', 'IdEmpresa', AConfig.IdEmpresa);
    Ini.WriteString('App', 'IAModelo', AConfig.IAModelo);
    Ini.WriteString('App', 'ApiKey', AConfig.ApiKey);
    
    Ini.WriteString('Notifications', 'EmailErrorDestino', AConfig.EmailErrorDestino);
    Ini.WriteString('Notifications', 'IdConfigEnvioError', AConfig.IdConfigEnvioError);
    
    SL := TStringList.Create;
    try
      Ini.GetStrings(SL);
      if SL.Count > 0 then
      begin
        S := EncryptText(SL.Text);
        // Escribir el archivo encriptado
        TFile.WriteAllText(GetConfigPath, S, TEncoding.UTF8);
      end;
    finally
      SL.Free;
    end;
    
    // Actualizar la variable global
    Config := AConfig;
  finally
    Ini.Free;
  end;
end;

class procedure TConfigHelper.SaveDefaultConfig;
var
  DefaultConfig: TAppConfig;
begin
  DefaultConfig.DBServer := '127.0.0.1';
  DefaultConfig.DBName   := 'agrigest';
  DefaultConfig.DBUser   := 'asesoft';
  DefaultConfig.DBPass   := 'Pantera1';
  DefaultConfig.DBPort   := 3306;
  
  DefaultConfig.PathRecepcion    := 'c:\agrigest\documentando';
  DefaultConfig.PathAlbaranes    := 'c:\agrigest\documentando\Albaranes';
  DefaultConfig.PathFacturas     := 'c:\agrigest\documentando\Facturas';
  DefaultConfig.PathTrabajadores := 'c:\agrigest\documentando\Trabajadores';
  DefaultConfig.PathErrores     := 'c:\agrigest\documentando\Errores';
  
  DefaultConfig.IdEmpresa := '1';
  DefaultConfig.EmailErrorDestino := '';
  DefaultConfig.IdConfigEnvioError := '';

  SaveConfig(DefaultConfig);
end;

initialization
  Config := TConfigHelper.LoadConfig;

end.
