unit frm_EquiposSensoresEditor;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.UITypes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Buttons,
  Data.DB, FireDAC.Comp.Client, FireDAC.Stan.Param, uAppTheme;

type
  TfrmEquiposSensoresEditor = class(TForm)
    pnlTop: TPanel;
    lblTitle: TLabel;
    pnlClient: TPanel;
    pnlBottom: TPanel;
    btnGuardar: TBitBtn;
    btnCancelar: TBitBtn;
    lblEquipo: TLabel;
    cbbEquipo: TComboBox;
    lblNombre: TLabel;
    edtNombre: TEdit;
    lblTipoSensor: TLabel;
    cbbTipoSensor: TComboBox;
    lblIdentificador: TLabel;
    edtIdentificador: TEdit;
    lblUmbralMin: TLabel;
    edtUmbralMin: TEdit;
    lblUmbralMax: TLabel;
    edtUmbralMax: TEdit;
    chkActivo: TCheckBox;
    lblAyudaMac: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure btnGuardarClick(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
  private
    FEditId: Integer;
    FIdEquipoFijo: Integer;
    procedure CargarEquipos;
    procedure CargarDatos;
  public
    property EditId: Integer read FEditId write FEditId;
    property IdEquipoFijo: Integer read FIdEquipoFijo write FIdEquipoFijo;
  end;

var
  frmEquiposSensoresEditor: TfrmEquiposSensoresEditor;

implementation

uses
  dmg_Main, uDbErrorHandler;

{$R *.dfm}

procedure TfrmEquiposSensoresEditor.FormCreate(Sender: TObject);
begin
  FEditId := 0;
  FIdEquipoFijo := 0;
end;

procedure TfrmEquiposSensoresEditor.FormShow(Sender: TObject);
begin
  TAppTheme.ApplyToForm(Self);

  CargarEquipos;

  if FEditId > 0 then
  begin
    lblTitle.Caption := '✏️ Editar Sensor de Equipo #' + IntToStr(FEditId);
    CargarDatos;
  end
  else
  begin
    lblTitle.Caption := '➕ Asignar Nuevo Sensor IoT';
    edtNombre.Text := '';
    cbbTipoSensor.ItemIndex := 0; // BLE_TEMP
    edtIdentificador.Text := '';
    edtUmbralMin.Text := '150,00';
    edtUmbralMax.Text := '260,00';
    chkActivo.Checked := True;
  end;

  edtNombre.SetFocus;
end;

procedure TfrmEquiposSensoresEditor.CargarEquipos;
var
  Qry: TFDQuery;
begin
  cbbEquipo.Items.Clear;
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text :=
      'SELECT e.id, CONCAT(e.codigo, '' - '', e.nombre, '' ('', z.nombre, '')'') AS equipo_desc ' +
      'FROM ge_zonas_equipos e ' +
      'INNER JOIN ge_centros_zonas z ON e.id_zona = z.id ' +
      'WHERE z.id_empresa = :emp AND e.activo = 1 ' +
      'ORDER BY z.nombre ASC, e.nombre ASC';
    Qry.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
    Qry.Open;
    while not Qry.Eof do
    begin
      cbbEquipo.Items.AddObject(Qry.FieldByName('equipo_desc').AsString, TObject(IntPtr(Qry.FieldByName('id').AsInteger)));
      Qry.Next;
    end;

    if cbbEquipo.Items.Count > 0 then
    begin
      cbbEquipo.ItemIndex := 0;
      if FIdEquipoFijo > 0 then
      begin
        for var i := 0 to cbbEquipo.Items.Count - 1 do
        begin
          if Integer(IntPtr(cbbEquipo.Items.Objects[i])) = FIdEquipoFijo then
          begin
            cbbEquipo.ItemIndex := i;
            Break;
          end;
        end;
      end;
    end;
  finally
    Qry.Free;
  end;
end;

procedure TfrmEquiposSensoresEditor.CargarDatos;
var
  Qry: TFDQuery;
begin
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text := 'SELECT * FROM ge_equipos_sensores WHERE id = :id';
    Qry.ParamByName('id').AsInteger := FEditId;
    Qry.Open;

    if not Qry.IsEmpty then
    begin
      var LEquipoId := Qry.FieldByName('id_equipo').AsInteger;
      for var i := 0 to cbbEquipo.Items.Count - 1 do
      begin
        if Integer(IntPtr(cbbEquipo.Items.Objects[i])) = LEquipoId then
        begin
          cbbEquipo.ItemIndex := i;
          Break;
        end;
      end;

      edtNombre.Text := Qry.FieldByName('nombre_sensor').AsString;
      
      var LTipo := Qry.FieldByName('tipo_sensor').AsString;
      var LIdx := cbbTipoSensor.Items.IndexOf(LTipo);
      if LIdx >= 0 then
        cbbTipoSensor.ItemIndex := LIdx
      else
        cbbTipoSensor.ItemIndex := 0;

      edtIdentificador.Text := Qry.FieldByName('identificador_hardware').AsString;
      edtUmbralMin.Text := FormatFloat('0.00', Qry.FieldByName('umbral_min_temp').AsFloat);
      edtUmbralMax.Text := FormatFloat('0.00', Qry.FieldByName('umbral_max_temp').AsFloat);
      if Qry.FieldByName('activo') is TBooleanField then
        chkActivo.Checked := Qry.FieldByName('activo').AsBoolean
      else
        chkActivo.Checked := (Qry.FieldByName('activo').AsString = '1') or (Qry.FieldByName('activo').AsString = 'True');
    end;
  finally
    Qry.Free;
  end;
end;

procedure TfrmEquiposSensoresEditor.btnGuardarClick(Sender: TObject);
var
  LEquipoId: Integer;
  LMin, LMax: Double;
  LTipoStr: string;
begin
  if Trim(edtNombre.Text) = '' then
  begin
    MessageDlg('Debe indicar un nombre descriptivo para el sensor.', mtWarning, [mbOK], 0);
    edtNombre.SetFocus;
    Exit;
  end;

  if cbbEquipo.ItemIndex < 0 then
  begin
    MessageDlg('Debe seleccionar el equipo/máquina asignado.', mtWarning, [mbOK], 0);
    cbbEquipo.SetFocus;
    Exit;
  end;

  LEquipoId := Integer(IntPtr(cbbEquipo.Items.Objects[cbbEquipo.ItemIndex]));
  LTipoStr := cbbTipoSensor.Text;
  if LTipoStr = '' then LTipoStr := 'BLE_TEMP';

  LMin := StrToFloatDef(Trim(StringReplace(edtUmbralMin.Text, ',', '.', [rfReplaceAll])), 0.0);
  LMax := StrToFloatDef(Trim(StringReplace(edtUmbralMax.Text, ',', '.', [rfReplaceAll])), 0.0);

  try
    dmgMain.qryExec.Close;
    if FEditId > 0 then
    begin
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_equipos_sensores SET ' +
        '  id_equipo = :equipo, nombre_sensor = :nom, tipo_sensor = :tipo, ' +
        '  identificador_hardware = :hw, umbral_min_temp = :min_t, umbral_max_temp = :max_t, ' +
        '  activo = :act ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id').AsInteger := FEditId;
    end
    else
    begin
      dmgMain.qryExec.SQL.Text :=
        'INSERT INTO ge_equipos_sensores (id_equipo, nombre_sensor, tipo_sensor, identificador_hardware, umbral_min_temp, umbral_max_temp, activo) ' +
        'VALUES (:equipo, :nom, :tipo, :hw, :min_t, :max_t, :act)';
    end;

    dmgMain.qryExec.ParamByName('equipo').AsInteger := LEquipoId;
    dmgMain.qryExec.ParamByName('nom').AsString := Trim(edtNombre.Text);
    dmgMain.qryExec.ParamByName('tipo').AsString := LTipoStr;
    dmgMain.qryExec.ParamByName('hw').AsString := Trim(edtIdentificador.Text);
    dmgMain.qryExec.ParamByName('min_t').AsFloat := LMin;
    dmgMain.qryExec.ParamByName('max_t').AsFloat := LMax;
    if chkActivo.Checked then
      dmgMain.qryExec.ParamByName('act').AsInteger := 1
    else
      dmgMain.qryExec.ParamByName('act').AsInteger := 0;

    dmgMain.qryExec.ExecSQL;

    ModalResult := mrOk;
  except
    on E: Exception do
      TDbErrorHandler.HandleException(E, 'Error al guardar el sensor de equipo');
  end;
end;

procedure TfrmEquiposSensoresEditor.btnCancelarClick(Sender: TObject);
begin
  ModalResult := mrCancel;
end;

end.
