unit frm_IncidenciasEditor;

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

type
  TfrmIncidenciasEditor = class(TfrmBase)
    lblId: TLabel;
    edtId: TEdit;
    lblFecha: TLabel;
    dtpFecha: TDateTimePicker;
    lblTipoOrigen: TLabel;
    cbTipoOrigen: TComboBox;
    lblOrigen: TLabel;
    cbOrigen: TComboBox;
    lblTitulo: TLabel;
    edtTitulo: TEdit;
    lblDescripcion: TLabel;
    memDescripcion: TMemo;
    lblSeveridad: TLabel;
    cbSeveridad: TComboBox;
    lblEstado: TLabel;
    cbEstado: TComboBox;
    
    // Panel/Controles de resolución
    pnlResolucion: TPanel;
    lblFechaResolucion: TLabel;
    dtpFechaResolucion: TDateTimePicker;
    lblComentariosResolucion: TLabel;
    memComentariosResolucion: TMemo;

    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnSalirClick(Sender: TObject);
    procedure cbTipoOrigenChange(Sender: TObject);
    procedure cbEstadoChange(Sender: TObject);
  protected
    procedure DoAnadir; override;
    procedure DoModificar; override;
    procedure DoPrimero; override;
    procedure DoAnterior; override;
    procedure DoSiguiente; override;
    procedure DoUltimo; override;
  private
    FIncidenciaId: string;
    FParentForm: TForm;
    FOrigenIds: TStringList;
    procedure LoadData;
    procedure LoadOrigenes;
    procedure AdjustResolucionPanel;
  public
    property IncidenciaId: string read FIncidenciaId write FIncidenciaId;
    property ParentForm: TForm read FParentForm write FParentForm;
  end;

var
  frmIncidenciasEditor: TfrmIncidenciasEditor;

implementation

uses
  dmg_Main, uDbErrorHandler, frm_Incidencias;

{$R *.dfm}

procedure TfrmIncidenciasEditor.FormShow(Sender: TObject);
begin
  if not Assigned(FOrigenIds) then
    FOrigenIds := TStringList.Create
  else
    FOrigenIds.Clear;

  TAppTheme.ApplyToForm(Self);

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

  pgcDetails.Visible := True;
  TsListado.TabVisible := False;
  pgcDetails.ActivePage := tsDatosEnvio;
  pnlSideToolbar.Visible := False;
  dbgItems.Visible := False;
  pnlFooter.Visible := False;

  edtId.ReadOnly := True;
  edtId.Color := clBtnFace;

  // Cargar combos fijos
  cbTipoOrigen.Items.Clear;
  cbTipoOrigen.Items.Add('ALMACEN');
  cbTipoOrigen.Items.Add('OBRADOR');
  cbTipoOrigen.ItemIndex := 0;

  cbSeveridad.Items.Clear;
  cbSeveridad.Items.Add('BAJA');
  cbSeveridad.Items.Add('MEDIA');
  cbSeveridad.Items.Add('ALTA');
  cbSeveridad.Items.Add('CRITICA');
  cbSeveridad.ItemIndex := 0;

  cbEstado.Items.Clear;
  cbEstado.Items.Add('ABIERTA');
  cbEstado.Items.Add('EN_PROCESO');
  cbEstado.Items.Add('RESUELTA');
  cbEstado.Items.Add('CERRADA');
  cbEstado.ItemIndex := 0;

  LoadOrigenes;

  if FIncidenciaId <> '' then
    LoadData
  else
    DoAnadir;

  AdjustResolucionPanel;
end;

procedure TfrmIncidenciasEditor.FormDestroy(Sender: TObject);
begin
  if Assigned(FOrigenIds) then
    FreeAndNil(FOrigenIds);
end;

procedure TfrmIncidenciasEditor.cbTipoOrigenChange(Sender: TObject);
begin
  LoadOrigenes;
end;

procedure TfrmIncidenciasEditor.cbEstadoChange(Sender: TObject);
begin
  AdjustResolucionPanel;
end;

procedure TfrmIncidenciasEditor.AdjustResolucionPanel;
var
  LEstado: string;
begin
  LEstado := cbEstado.Text;
  pnlResolucion.Visible := SameText(LEstado, 'RESUELTA') or SameText(LEstado, 'CERRADA');
end;

procedure TfrmIncidenciasEditor.LoadOrigenes;
var
  LQuery: TFDQuery;
begin
  cbOrigen.Items.Clear;
  FOrigenIds.Clear;

  if dmgMain.CurrentCompanyId = '' then Exit;

  LQuery := TFDQuery.Create(nil);
  try
    LQuery.Connection := dmgMain.dbConn;
    if cbTipoOrigen.ItemIndex = 0 then
    begin
      LQuery.SQL.Text := 'SELECT id, descripcion as nombre FROM ge_almacenes WHERE id_empresa = :emp AND activo = true ORDER BY descripcion';
    end
    else
    begin
      LQuery.SQL.Text := 'SELECT id, nombre FROM ge_obradores WHERE id_empresa = :emp AND activo = true ORDER BY nombre';
    end;
    LQuery.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
    LQuery.Open;

    while not LQuery.Eof do
    begin
      cbOrigen.Items.Add(LQuery.FieldByName('nombre').AsString);
      FOrigenIds.Add(TdmgMain.CleanUUID(LQuery.FieldByName('id').AsString));
      LQuery.Next;
    end;
  finally
    LQuery.Free;
  end;

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

procedure TfrmIncidenciasEditor.LoadData;
var
  LOrigenId: string;
begin
  if FIncidenciaId = '' then Exit;

  dmgMain.qryExec.Close;
  dmgMain.qryExec.SQL.Text := 'SELECT * FROM ge_incidencias_obrador WHERE id = :id';
  dmgMain.qryExec.ParamByName('id').AsString := FIncidenciaId;
  dmgMain.qryExec.Open;
  
  if not dmgMain.qryExec.IsEmpty then
  begin
    edtId.Text := FIncidenciaId;
    dtpFecha.DateTime := dmgMain.qryExec.FieldByName('fecha').AsDateTime;
    edtTitulo.Text := dmgMain.qryExec.FieldByName('titulo').AsString;
    memDescripcion.Text := dmgMain.qryExec.FieldByName('descripcion').AsString;
    
    cbTipoOrigen.ItemIndex := cbTipoOrigen.Items.IndexOf(dmgMain.qryExec.FieldByName('tipo_origin').AsString);
    if cbTipoOrigen.ItemIndex = -1 then
    begin
      cbTipoOrigen.ItemIndex := cbTipoOrigen.Items.IndexOf(dmgMain.qryExec.FieldByName('tipo_origen').AsString);
    end;
    
    LoadOrigenes;
    
    LOrigenId := TdmgMain.CleanUUID(dmgMain.qryExec.FieldByName('origen_id').AsString);
    cbOrigen.ItemIndex := FOrigenIds.IndexOf(LOrigenId);
    
    cbSeveridad.ItemIndex := cbSeveridad.Items.IndexOf(dmgMain.qryExec.FieldByName('severidad').AsString);
    cbEstado.ItemIndex := cbEstado.Items.IndexOf(dmgMain.qryExec.FieldByName('estado').AsString);
    
    if not dmgMain.qryExec.FieldByName('fecha_resolucion').IsNull then
      dtpFechaResolucion.DateTime := dmgMain.qryExec.FieldByName('fecha_resolucion').AsDateTime
    else
      dtpFechaResolucion.DateTime := Now;
      
    memComentariosResolucion.Text := dmgMain.qryExec.FieldByName('comentarios_resolucion').AsString;
  end;
  dmgMain.qryExec.Close;
end;

procedure TfrmIncidenciasEditor.DoAnadir;
begin
  FIncidenciaId := '';
  edtId.Text := '(Nueva)';
  dtpFecha.DateTime := Now;
  edtTitulo.Clear;
  memDescripcion.Clear;
  cbTipoOrigen.ItemIndex := 0;
  LoadOrigenes;
  cbSeveridad.ItemIndex := 0;
  cbEstado.ItemIndex := 0;
  dtpFechaResolucion.DateTime := Now;
  memComentariosResolucion.Clear;
  edtTitulo.SetFocus;
end;

procedure TfrmIncidenciasEditor.DoModificar;
begin
  edtTitulo.SetFocus;
end;

procedure TfrmIncidenciasEditor.DoPrimero;
var
  LParent: TfrmIncidencias;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmIncidencias) then
    LParent := TfrmIncidencias(FParentForm)
  else if Assigned(frmIncidencias) then
    LParent := frmIncidencias;

  if Assigned(LParent) and Assigned(LParent.QryMain) and not LParent.QryMain.IsEmpty then
  begin
    LParent.QryMain.First;
    FIncidenciaId := LParent.QryMain.FieldByName('id').AsString;
    LoadData;
    AdjustResolucionPanel;
  end;
end;

procedure TfrmIncidenciasEditor.DoAnterior;
var
  LParent: TfrmIncidencias;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmIncidencias) then
    LParent := TfrmIncidencias(FParentForm)
  else if Assigned(frmIncidencias) then
    LParent := frmIncidencias;

  if Assigned(LParent) and Assigned(LParent.QryMain) and not LParent.QryMain.IsEmpty then
  begin
    LParent.QryMain.Prior;
    FIncidenciaId := LParent.QryMain.FieldByName('id').AsString;
    LoadData;
    AdjustResolucionPanel;
  end;
end;

procedure TfrmIncidenciasEditor.DoSiguiente;
var
  LParent: TfrmIncidencias;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmIncidencias) then
    LParent := TfrmIncidencias(FParentForm)
  else if Assigned(frmIncidencias) then
    LParent := frmIncidencias;

  if Assigned(LParent) and Assigned(LParent.QryMain) and not LParent.QryMain.IsEmpty then
  begin
    LParent.QryMain.Next;
    FIncidenciaId := LParent.QryMain.FieldByName('id').AsString;
    LoadData;
    AdjustResolucionPanel;
  end;
end;

procedure TfrmIncidenciasEditor.DoUltimo;
var
  LParent: TfrmIncidencias;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmIncidencias) then
    LParent := TfrmIncidencias(FParentForm)
  else if Assigned(frmIncidencias) then
    LParent := frmIncidencias;

  if Assigned(LParent) and Assigned(LParent.QryMain) and not LParent.QryMain.IsEmpty then
  begin
    LParent.QryMain.Last;
    FIncidenciaId := LParent.QryMain.FieldByName('id').AsString;
    LoadData;
    AdjustResolucionPanel;
  end;
end;

procedure TfrmIncidenciasEditor.btnSalirClick(Sender: TObject);
begin
  Close;
end;

procedure TfrmIncidenciasEditor.btnSaveClick(Sender: TObject);
var
  LIsNew: Boolean;
  LEstado: string;
  LNewId: Integer;
begin
  if Trim(edtTitulo.Text) = '' then
  begin
    ShowMessage('Debe introducir el título de la incidencia.');
    edtTitulo.SetFocus;
    Exit;
  end;

  if cbOrigen.ItemIndex = -1 then
  begin
    ShowMessage('Debe seleccionar un almacén u obrador de origen.');
    cbOrigen.SetFocus;
    Exit;
  end;

  LIsNew := (FIncidenciaId = '');
  LNewId := 0;
  try
    dmgMain.qryExec.Close;
    if LIsNew then
    begin
      dmgMain.qryExec.SQL.Text := 'SELECT COALESCE(MAX(id), 0) + 1 as next_id FROM ge_incidencias_obrador';
      dmgMain.qryExec.Open;
      LNewId := dmgMain.qryExec.FieldByName('next_id').AsInteger;
      dmgMain.qryExec.Close;

      dmgMain.qryExec.SQL.Text := 
        'INSERT INTO ge_incidencias_obrador (id, empresa_id, tipo_origen, origen_id, fecha, titulo, descripcion, severidad, estado, fecha_resolucion, comentarios_resolucion, id_user_creator, id_user_update) ' +
        'VALUES (:id, :emp, :tipo_origen, :origen_id, :fecha, :titulo, :descripcion, :severidad, :estado, :fecha_res, :coment_res, :user, :user)';
      dmgMain.qryExec.ParamByName('id').AsInteger := LNewId;
    end
    else
    begin
      dmgMain.qryExec.SQL.Text := 
        'UPDATE ge_incidencias_obrador SET tipo_origen = :tipo_origen, origen_id = :origen_id, fecha = :fecha, ' +
        'titulo = :titulo, descripcion = :descripcion, severidad = :severidad, estado = :estado, ' +
        'fecha_resolucion = :fecha_res, comentarios_resolucion = :coment_res, ' +
        'id_user_update = :user, updated_at = CURRENT_TIMESTAMP ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id').AsString := FIncidenciaId;
    end;
    dmgMain.qryExec.ParamByName('tipo_origen').AsString := cbTipoOrigen.Text;
    dmgMain.qryExec.ParamByName('origen_id').AsString := FOrigenIds[cbOrigen.ItemIndex];
    dmgMain.qryExec.ParamByName('fecha').AsDateTime := dtpFecha.DateTime;
    dmgMain.qryExec.ParamByName('titulo').AsString := Trim(edtTitulo.Text);
    dmgMain.qryExec.ParamByName('descripcion').AsString := Trim(memDescripcion.Text);
    dmgMain.qryExec.ParamByName('severidad').AsString := cbSeveridad.Text;
    
    LEstado := cbEstado.Text;
    dmgMain.qryExec.ParamByName('estado').AsString := LEstado;
    
    if SameText(LEstado, 'RESUELTA') or SameText(LEstado, 'CERRADA') then
    begin
      dmgMain.qryExec.ParamByName('fecha_res').AsDateTime := dtpFechaResolucion.DateTime;
      dmgMain.qryExec.ParamByName('coment_res').AsString := Trim(memComentariosResolucion.Text);
    end
    else
    begin
      dmgMain.qryExec.ParamByName('fecha_res').Clear;
      dmgMain.qryExec.ParamByName('coment_res').Clear;
    end;

    if LIsNew then
      dmgMain.qryExec.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
      
    dmgMain.qryExec.ParamByName('user').AsString := dmgMain.CurrentUserId;
    
    dmgMain.qryExec.ExecSQL;
    
    if LIsNew then
    begin
      FIncidenciaId := IntToStr(LNewId);
      edtId.Text := FIncidenciaId;
    end;
    
    ResetChangeTracking;
    ShowMessage('Incidencia guardada correctamente.');

    if Assigned(FParentForm) and (FParentForm is TfrmIncidencias) then
    begin
      TfrmIncidencias(FParentForm).btnRefreshClick(nil);
      TfrmIncidencias(FParentForm).QryMain.Locate('id', FIncidenciaId, []);
    end;
  except
    on E: Exception do
      TDbErrorHandler.HandleException(E, 'Error al guardar la incidencia');
  end;
end;

end.
