unit frm_DbErrorDialog;

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,
  Vcl.Clipbrd, uDbErrorHandler, uAppTheme;

type
  TfrmDbErrorDialog = class(TForm)
    pnlHeader: TPanel;
    lblErrorTitle: TLabel;
    pnlClient: TPanel;
    lblFriendlyMessage: TLabel;
    pnlButtons: TPanel;
    btnAccept: TButton;
    btnDetails: TButton;
    btnCopy: TButton;
    pnlDetails: TPanel;
    memDetails: TMemo;
    procedure btnDetailsClick(Sender: TObject);
    procedure btnCopyClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FDetails: TDbErrorDetails;
    FIsExpanded: Boolean;
    procedure SetDetails(const ADetails: TDbErrorDetails);
    procedure ToggleDetails;
    procedure StyleForErrorType;
  public
    class procedure ShowError(const ADetails: TDbErrorDetails);
  end;

var
  frmDbErrorDialog: TfrmDbErrorDialog;

implementation

{$R *.dfm}

{ TfrmDbErrorDialog }

class procedure TfrmDbErrorDialog.ShowError(const ADetails: TDbErrorDetails);
var
  LForm: TfrmDbErrorDialog;
begin
  LForm := TfrmDbErrorDialog.Create(Application);
  try
    LForm.SetDetails(ADetails);
    LForm.ShowModal;
  finally
    LForm.Free;
  end;
end;

procedure TfrmDbErrorDialog.FormCreate(Sender: TObject);
begin
  FIsExpanded := False;
  pnlDetails.Visible := False;
  btnCopy.Visible := False;
  
  // Establecer dimensiones iniciales (colapsado)
  ClientHeight := 195;
  ClientWidth := 530;
  
  // Aplicar tema corporativo inicial
  TAppTheme.ApplyToForm(Self);
end;

procedure TfrmDbErrorDialog.FormShow(Sender: TObject);
begin
  StyleForErrorType;
end;

procedure TfrmDbErrorDialog.SetDetails(const ADetails: TDbErrorDetails);
var
  LTechnicalInfo: TStringList;
begin
  FDetails := ADetails;
  
  // Mensaje amigable al usuario
  lblFriendlyMessage.Caption := FDetails.FriendlyMessage;
  
  // Construir la información técnica detallada
  LTechnicalInfo := TStringList.Create;
  try
    LTechnicalInfo.Add('=== DETALLES TÉCNICOS DE ERROR DE BASE DE DATOS ===');
    LTechnicalInfo.Add(Format('Fecha/Hora: %s', [DateTimeToStr(Now)]));
    if FDetails.ModuleName <> '' then
      LTechnicalInfo.Add(Format('Módulo / Formulario Origen: %s', [FDetails.ModuleName]));
    if FDetails.ProcedureName <> '' then
      LTechnicalInfo.Add(Format('Procedimiento / Evento: %s', [FDetails.ProcedureName]));
    
    case FDetails.ErrorType of
      detDuplicateKey:     LTechnicalInfo.Add('Categoría: Clave Duplicada (Unique Violation)');
      detForeignKey:       LTechnicalInfo.Add('Categoría: Integridad Referencial (Foreign Key)');
      detNotNull:          LTechnicalInfo.Add('Categoría: Campo Obligatorio Vacío (Not Null Violation)');
      detDataTruncation:   LTechnicalInfo.Add('Categoría: Truncado de Datos (String/Data Too Long)');
      detConnectionLost:   LTechnicalInfo.Add('Categoría: Conexión de Red Perdida (Connection Failure)');
      detDeadlock:         LTechnicalInfo.Add('Categoría: Conflicto de Bloqueo (Deadlock/Serialization)');
      detPermissionDenied: LTechnicalInfo.Add('Categoría: Permiso Denegado (Insufficient Privilege)');
      detStructureError:   LTechnicalInfo.Add('Categoría: Incompatibilidad de Estructura (Db Schema Mismatch)');
      detOther:            LTechnicalInfo.Add('Categoría: Otro Error de Base de Datos / Sistema');
    end;
    
    if FDetails.SqlState <> '' then
      LTechnicalInfo.Add(Format('SQLSTATE: %s', [FDetails.SqlState]));
      
    if FDetails.ConstraintName <> '' then
      LTechnicalInfo.Add(Format('Restricción (Constraint): %s', [FDetails.ConstraintName]));
      
    if FDetails.TableName <> '' then
      LTechnicalInfo.Add(Format('Tabla Afectada: %s', [FDetails.TableName]));
      
    if FDetails.FieldName <> '' then
      LTechnicalInfo.Add(Format('Columna Afectada: %s', [FDetails.FieldName]));
      
    LTechnicalInfo.Add('');
    LTechnicalInfo.Add('Mensaje original del motor:');
    LTechnicalInfo.Add(FDetails.OriginalMessage);
    
    if FDetails.SqlText <> '' then
    begin
      LTechnicalInfo.Add('');
      LTechnicalInfo.Add('Sentencia SQL ejecutada:');
      LTechnicalInfo.Add(FDetails.SqlText);
    end;
    
    memDetails.Text := LTechnicalInfo.Text;
  finally
    LTechnicalInfo.Free;
  end;
end;

procedure TfrmDbErrorDialog.StyleForErrorType;
begin
  // Personalizar el título del banner superior y su color de fondo para impactar visualmente
  case FDetails.ErrorType of
    detConnectionLost:
      begin
        lblErrorTitle.Caption := '🔌 Error de Conexión a Base de Datos';
        // Color rojo oscuro de alerta / crítico
        pnlHeader.Color := $1515B3; // BGR para Rojo Alerta Brillante (#B31515)
      end;
      
    detDuplicateKey:
      begin
        lblErrorTitle.Caption := '📝 Registro Duplicado / Ya Existente';
        pnlHeader.Color := TAppTheme.COLOR_MAIN_RED; // Rojo Corporativo Raúl Asencio
      end;
      
    detForeignKey:
      begin
        lblErrorTitle.Caption := '🔗 Conflicto de Relación de Datos';
        pnlHeader.Color := $0080FF; // BGR para Naranja Elegante (#FF8000)
      end;
      
    detNotNull:
      begin
        lblErrorTitle.Caption := '⚠️ Campo Obligatorio Requerido';
        pnlHeader.Color := $0080FF; // Naranja Elegante
      end;
      
    detDeadlock:
      begin
        lblErrorTitle.Caption := '⏳ Conflicto de Concurrencia (Bloqueo)';
        pnlHeader.Color := $1F7A7A; // BGR para Gris-Marrón/Ocre (#7A7A1F)
      end;
      
    detPermissionDenied:
      begin
        lblErrorTitle.Caption := '🚫 Permisos Insuficientes';
        pnlHeader.Color := $1515B3; // Rojo Alerta
      end;
      
    else
      begin
        lblErrorTitle.Caption := '❌ Error del Sistema de Base de Datos';
        pnlHeader.Color := TAppTheme.COLOR_MAIN_RED; // Rojo Corporativo
      end;
  end;
  
  // Configurar fuentes premium del banner
  lblErrorTitle.Font.Name := TAppTheme.FONT_NAME_HEADER;
  lblErrorTitle.Font.Size := 13;
  lblErrorTitle.Font.Style := [fsBold];
  lblErrorTitle.Font.Color := clWhite;
  
  // Mensaje amigable
  lblFriendlyMessage.Font.Name := TAppTheme.FONT_NAME_MAIN;
  lblFriendlyMessage.Font.Size := 10;
  lblFriendlyMessage.Font.Color := TAppTheme.COLOR_TEXT_DARK;
end;

procedure TfrmDbErrorDialog.btnDetailsClick(Sender: TObject);
begin
  ToggleDetails;
end;

procedure TfrmDbErrorDialog.ToggleDetails;
begin
  FIsExpanded := not FIsExpanded;
  
  // Animar o ajustar tamaño
  pnlDetails.Visible := FIsExpanded;
  btnCopy.Visible := FIsExpanded;
  
  if FIsExpanded then
  begin
    btnDetails.Caption := '<< Ocultar detalles técnicos';
    ClientHeight := 380;
  end
  else
  begin
    btnDetails.Caption := 'Ver detalles técnicos >>';
    ClientHeight := 195;
  end;
end;

procedure TfrmDbErrorDialog.btnCopyClick(Sender: TObject);
begin
  Clipboard.AsText := memDetails.Text;
  ShowMessage('Los detalles técnicos se han copiado al portapapeles. Puede pegarlos en un correo o chat de soporte.');
end;

end.
