unit frm_CentrosZonasEditor;

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
  TfrmCentrosZonasEditor = class(TForm)
    pnlTop: TPanel;
    lblTitle: TLabel;
    pnlClient: TPanel;
    pnlBottom: TPanel;
    btnGuardar: TBitBtn;
    btnCancelar: TBitBtn;
    lblTipoCentro: TLabel;
    cbbTipoCentro: TComboBox;
    lblCentro: TLabel;
    cbbCentro: TComboBox;
    lblCodigo: TLabel;
    edtCodigo: TEdit;
    lblNombre: TLabel;
    edtNombre: TEdit;
    lblColor: TLabel;
    cbbColor: TColorBox;
    lblOrden: TLabel;
    edtOrden: TEdit;
    chkActivo: TCheckBox;
    lblObservaciones: TLabel;
    mmoObservaciones: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure cbbTipoCentroChange(Sender: TObject);
    procedure btnGuardarClick(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
  private
    FEditId: Integer;
    FTipoCentroFijo: string;
    FIdCentroFijo: Integer;
    procedure CargarCentros;
    procedure CargarDatos;
  public
    property EditId: Integer read FEditId write FEditId;
    property TipoCentroFijo: string read FTipoCentroFijo write FTipoCentroFijo;
    property IdCentroFijo: Integer read FIdCentroFijo write FIdCentroFijo;
  end;

var
  frmCentrosZonasEditor: TfrmCentrosZonasEditor;

implementation

uses
  dmg_Main, uDbErrorHandler;

{$R *.dfm}

procedure TfrmCentrosZonasEditor.FormCreate(Sender: TObject);
begin
  FEditId := 0;
  FTipoCentroFijo := '';
  FIdCentroFijo := 0;
end;

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

  if FTipoCentroFijo <> '' then
  begin
    if FTipoCentroFijo = 'ALMACEN' then
      cbbTipoCentro.ItemIndex := 1
    else
      cbbTipoCentro.ItemIndex := 0;
    cbbTipoCentro.Enabled := False;
  end;

  CargarCentros;

  if FEditId > 0 then
  begin
    lblTitle.Caption := '✏️ Editar Zona Operativa #' + IntToStr(FEditId);
    CargarDatos;
  end
  else
  begin
    lblTitle.Caption := '➕ Nueva Zona Operativa';
    edtCodigo.Text := '';
    edtNombre.Text := '';
    cbbColor.Selected := clHighlight;
    edtOrden.Text := '1';
    chkActivo.Checked := True;
    mmoObservaciones.Clear;
  end;

  edtCodigo.SetFocus;
end;

procedure TfrmCentrosZonasEditor.cbbTipoCentroChange(Sender: TObject);
begin
  CargarCentros;
end;

procedure TfrmCentrosZonasEditor.CargarCentros;
var
  Qry: TFDQuery;
  LTipo: string;
begin
  cbbCentro.Items.Clear;
  LTipo := 'OBRADOR';
  if cbbTipoCentro.ItemIndex = 1 then
    LTipo := 'ALMACEN';

  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    if LTipo = 'OBRADOR' then
    begin
      Qry.SQL.Text := 'SELECT id, nombre FROM ge_obradores WHERE id_empresa = :emp AND activo = 1 ORDER BY nombre ASC';
      Qry.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
      Qry.Open;
      while not Qry.Eof do
      begin
        cbbCentro.Items.AddObject(Qry.FieldByName('nombre').AsString, TObject(IntPtr(Qry.FieldByName('id').AsInteger)));
        Qry.Next;
      end;
    end
    else
    begin
      Qry.SQL.Text := 'SELECT id, descripcion AS nombre FROM ge_almacenes WHERE (id_empresa = :emp OR compartido = 1) AND activo = 1 ORDER BY descripcion ASC';
      Qry.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
      Qry.Open;
      while not Qry.Eof do
      begin
        cbbCentro.Items.AddObject(Qry.FieldByName('nombre').AsString, TObject(IntPtr(Qry.FieldByName('id').AsInteger)));
        Qry.Next;
      end;
    end;

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

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

    if not Qry.IsEmpty then
    begin
      if Qry.FieldByName('tipo_centro').AsString = 'ALMACEN' then
        cbbTipoCentro.ItemIndex := 1
      else
        cbbTipoCentro.ItemIndex := 0;

      CargarCentros;
      var LCentroId := Qry.FieldByName('id_centro').AsInteger;
      for var i := 0 to cbbCentro.Items.Count - 1 do
      begin
        if Integer(IntPtr(cbbCentro.Items.Objects[i])) = LCentroId then
        begin
          cbbCentro.ItemIndex := i;
          Break;
        end;
      end;

      edtCodigo.Text := Qry.FieldByName('codigo').AsString;
      edtNombre.Text := Qry.FieldByName('nombre').AsString;
      var LColorHex := Qry.FieldByName('color').AsString;
      if LColorHex <> '' then
      begin
        try
          cbbColor.Selected := StringToColor(LColorHex);
        except
          cbbColor.Selected := clHighlight;
        end;
      end;
      edtOrden.Text := Qry.FieldByName('orden').AsString;
      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 TfrmCentrosZonasEditor.btnGuardarClick(Sender: TObject);
var
  LTipo: string;
  LCentroId, LOrden: Integer;
  LColorHex: string;
begin
  if Trim(edtCodigo.Text) = '' then
  begin
    MessageDlg('Debe indicar un código para la zona.', mtWarning, [mbOK], 0);
    edtCodigo.SetFocus;
    Exit;
  end;

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

  if cbbCentro.ItemIndex < 0 then
  begin
    MessageDlg('Debe seleccionar un centro (obrador o almacén).', mtWarning, [mbOK], 0);
    cbbCentro.SetFocus;
    Exit;
  end;

  LTipo := 'OBRADOR';
  if cbbTipoCentro.ItemIndex = 1 then
    LTipo := 'ALMACEN';

  LCentroId := Integer(IntPtr(cbbCentro.Items.Objects[cbbCentro.ItemIndex]));
  LOrden := StrToIntDef(Trim(edtOrden.Text), 1);
  LColorHex := ColorToString(cbbColor.Selected);

  try
    dmgMain.qryExec.Close;
    if FEditId > 0 then
    begin
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_centros_zonas SET ' +
        '  tipo_centro = :tipo, id_centro = :centro, id_empresa = :emp, codigo = :cod, nombre = :nom, ' +
        '  color = :color, orden = :ord, 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_centros_zonas (tipo_centro, id_centro, id_empresa, codigo, nombre, color, orden, activo, observaciones, id_user_creator, id_user_update) ' +
        'VALUES (:tipo, :centro, :emp, :cod, :nom, :color, :ord, :act, :obs, :user, :user)';
    end;

    dmgMain.qryExec.ParamByName('tipo').AsString := LTipo;
    dmgMain.qryExec.ParamByName('centro').AsInteger := LCentroId;
    dmgMain.qryExec.ParamByName('emp').AsString := dmgMain.CurrentCompanyId;
    dmgMain.qryExec.ParamByName('cod').AsString := Trim(edtCodigo.Text);
    dmgMain.qryExec.ParamByName('nom').AsString := Trim(edtNombre.Text);
    dmgMain.qryExec.ParamByName('color').AsString := LColorHex;
    dmgMain.qryExec.ParamByName('ord').AsInteger := LOrden;
    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 la zona operativa');
  end;
end;

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

end.
