unit frm_ZonasEquiposEditor;

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
  TfrmZonasEquiposEditor = class(TForm)
    pnlTop: TPanel;
    lblTitle: TLabel;
    pnlClient: TPanel;
    pnlBottom: TPanel;
    btnGuardar: TBitBtn;
    btnCancelar: TBitBtn;
    lblZona: TLabel;
    cbbZona: TComboBox;
    lblCodigo: TLabel;
    edtCodigo: TEdit;
    lblNombre: TLabel;
    edtNombre: TEdit;
    lblTipoEquipo: TLabel;
    cbbTipoEquipo: TComboBox;
    lblMarcaModelo: TLabel;
    edtMarcaModelo: TEdit;
    lblCapacidad: TLabel;
    edtCapacidad: TEdit;
    lblCosteHora: TLabel;
    edtCosteHora: TEdit;
    chkActivo: TCheckBox;
    lblObservaciones: TLabel;
    mmoObservaciones: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure btnGuardarClick(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
  private
    FEditId: Integer;
    FIdZonaFija: Integer;
    procedure CargarZonas;
    procedure CargarDatos;
  public
    property EditId: Integer read FEditId write FEditId;
    property IdZonaFija: Integer read FIdZonaFija write FIdZonaFija;
  end;

var
  frmZonasEquiposEditor: TfrmZonasEquiposEditor;

implementation

uses
  dmg_Main, uDbErrorHandler;

{$R *.dfm}

procedure TfrmZonasEquiposEditor.FormCreate(Sender: TObject);
begin
  FEditId := 0;
  FIdZonaFija := 0;
end;

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

  CargarZonas;

  if FEditId > 0 then
  begin
    lblTitle.Caption := '✏️ Editar Equipo / Máquina #' + IntToStr(FEditId);
    CargarDatos;
  end
  else
  begin
    lblTitle.Caption := '➕ Nuevo Equipo / Máquina';
    edtCodigo.Text := '';
    edtNombre.Text := '';
    cbbTipoEquipo.ItemIndex := 0; // HORNO
    edtMarcaModelo.Text := '';
    edtCapacidad.Text := '0';
    edtCosteHora.Text := '0,00';
    chkActivo.Checked := True;
    mmoObservaciones.Clear;
  end;

  edtCodigo.SetFocus;
end;

procedure TfrmZonasEquiposEditor.CargarZonas;
var
  Qry: TFDQuery;
begin
  cbbZona.Items.Clear;
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text :=
      'SELECT z.id, CONCAT(CASE WHEN z.tipo_centro = ''OBRADOR'' THEN ''🏭 '' ELSE ''📦 '' END, z.codigo, '' - '', z.nombre) AS zona_desc ' +
      'FROM ge_centros_zonas z ' +
      'WHERE z.id_empresa = :emp AND z.activo = 1 ' +
      'ORDER BY z.tipo_centro ASC, z.orden ASC, z.nombre ASC';
    Qry.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
    Qry.Open;
    while not Qry.Eof do
    begin
      cbbZona.Items.AddObject(Qry.FieldByName('zona_desc').AsString, TObject(IntPtr(Qry.FieldByName('id').AsInteger)));
      Qry.Next;
    end;

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

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

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

      edtCodigo.Text := Qry.FieldByName('codigo').AsString;
      edtNombre.Text := Qry.FieldByName('nombre').AsString;
      
      var LTipo := Qry.FieldByName('tipo_equipo').AsString;
      var LIdx := cbbTipoEquipo.Items.IndexOf(LTipo);
      if LIdx >= 0 then
        cbbTipoEquipo.ItemIndex := LIdx
      else
        cbbTipoEquipo.ItemIndex := 0;

      edtMarcaModelo.Text := Qry.FieldByName('marca_modelo').AsString;
      edtCapacidad.Text := FormatFloat('0.##', Qry.FieldByName('capacidad_max').AsFloat);
      edtCosteHora.Text := FormatFloat('0.00', Qry.FieldByName('coste_hora_maquina').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');
      mmoObservaciones.Text := Qry.FieldByName('observaciones').AsString;
    end;
  finally
    Qry.Free;
  end;
end;

procedure TfrmZonasEquiposEditor.btnGuardarClick(Sender: TObject);
var
  LZonaId: Integer;
  LCapacidad, LCosteHora: Double;
  LTipoStr: string;
begin
  if Trim(edtCodigo.Text) = '' then
  begin
    MessageDlg('Debe indicar un código para el equipo/máquina.', mtWarning, [mbOK], 0);
    edtCodigo.SetFocus;
    Exit;
  end;

  if Trim(edtNombre.Text) = '' then
  begin
    MessageDlg('Debe indicar el nombre del equipo.', mtWarning, [mbOK], 0);
    edtNombre.SetFocus;
    Exit;
  end;

  if cbbZona.ItemIndex < 0 then
  begin
    MessageDlg('Debe seleccionar la zona a la que pertenece el equipo.', mtWarning, [mbOK], 0);
    cbbZona.SetFocus;
    Exit;
  end;

  LZonaId := Integer(IntPtr(cbbZona.Items.Objects[cbbZona.ItemIndex]));
  LTipoStr := cbbTipoEquipo.Text;
  if LTipoStr = '' then LTipoStr := 'HORNO';

  LCapacidad := StrToFloatDef(Trim(StringReplace(edtCapacidad.Text, ',', '.', [rfReplaceAll])), 0.0);
  LCosteHora := StrToFloatDef(Trim(StringReplace(edtCosteHora.Text, ',', '.', [rfReplaceAll])), 0.0);

  try
    dmgMain.qryExec.Close;
    if FEditId > 0 then
    begin
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_zonas_equipos SET ' +
        '  id_zona = :zona, codigo = :cod, nombre = :nom, tipo_equipo = :tipo, ' +
        '  marca_modelo = :marca, capacidad_max = :cap, coste_hora_maquina = :coste, ' +
        '  activo = :act, observaciones = :obs, id_user_update = :user ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id').AsInteger := FEditId;
    end
    else
    begin
      dmgMain.qryExec.SQL.Text :=
        'INSERT INTO ge_zonas_equipos (id_zona, codigo, nombre, tipo_equipo, marca_modelo, capacidad_max, coste_hora_maquina, activo, observaciones, id_user_creator, id_user_update) ' +
        'VALUES (:zona, :cod, :nom, :tipo, :marca, :cap, :coste, :act, :obs, :user, :user)';
    end;

    dmgMain.qryExec.ParamByName('zona').AsInteger := LZonaId;
    dmgMain.qryExec.ParamByName('cod').AsString := Trim(edtCodigo.Text);
    dmgMain.qryExec.ParamByName('nom').AsString := Trim(edtNombre.Text);
    dmgMain.qryExec.ParamByName('tipo').AsString := LTipoStr;
    dmgMain.qryExec.ParamByName('marca').AsString := Trim(edtMarcaModelo.Text);
    dmgMain.qryExec.ParamByName('cap').AsFloat := LCapacidad;
    dmgMain.qryExec.ParamByName('coste').AsFloat := LCosteHora;
    if chkActivo.Checked then
      dmgMain.qryExec.ParamByName('act').AsInteger := 1
    else
      dmgMain.qryExec.ParamByName('act').AsInteger := 0;
    dmgMain.qryExec.ParamByName('obs').AsString := Trim(mmoObservaciones.Text);
    dmgMain.qryExec.ParamByName('user').AsString := dmgMain.CurrentUserId;
    dmgMain.qryExec.ExecSQL;

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

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

end.
