unit frm_ProveedoresEditor;

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, System.UITypes;

type
  TfrmProveedoresEditor = class(TfrmBase)
    lblNombre: TLabel;
    edtNombre: TEdit;
    lblNIF: TLabel;
    edtNIF: TEdit;
    lblCodigo: TLabel;
    edtId: TEdit;
    lblDireccion: TLabel;
    edtDireccion: TEdit;
    lblCodigoPostal: TLabel;
    edtCodigoPostal: TEdit;
    lblPoblacion: TLabel;
    edtPoblacion: TEdit;
    lblProvincia: TLabel;
    edtProvincia: TEdit;
    lblTelefono1: TLabel;
    edtTelefono1: TEdit;
    lblTelefono2: TLabel;
    edtTelefono2: TEdit;
    lblEmail: TLabel;
    edtEmail: TEdit;
    lblContacto: TLabel;
    edtContacto: TEdit;
    lblObservaciones: TLabel;
    edtObservaciones: TEdit;
    chkActivo: TCheckBox;
    lblTipo: TLabel;
    cbTipo: TComboBox;

    // Pestañas y Rejillas de Diseño
    tsArticulos: TTabSheet;
    dbgArticulos: TDBGrid;
    qArticulos: TFDQuery;
    dsArticulos: TDataSource;

    tsAlbaranes: TTabSheet;
    dbgAlbaranes: TDBGrid;
    qAlbaranes: TFDQuery;
    dsAlbaranes: TDataSource;

    tsFacturas: TTabSheet;
    dbgFacturas: TDBGrid;
    qFacturas: TFDQuery;
    dsFacturas: TDataSource;

    procedure FormShow(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnSalirClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  protected
    procedure Loaded; override;
    procedure DoAnadir; override;
    procedure DoModificar; override;
    procedure DoPrimero; override;
    procedure DoAnterior; override;
    procedure DoSiguiente; override;
    procedure DoUltimo; override;
  private
    FProveedorId: string;
    FParentForm: TForm;
    procedure LoadData;
    procedure dbgArticulosDblClick(Sender: TObject);
    procedure dbgAlbaranesDblClick(Sender: TObject);
    procedure dbgFacturasDblClick(Sender: TObject);
  public
    property ProveedorId: string read FProveedorId write FProveedorId;
    property ParentForm: TForm read FParentForm write FParentForm;
  end;

var
  frmProveedoresEditor: TfrmProveedoresEditor;

implementation

uses
  dmg_Main, uDbErrorHandler, frm_Proveedores,
  frm_AsignarMateriasPrimas, frm_ProvAlbaranesEditor, frm_ProvFacturasEditor,
  uValidacionFiscal;

{$R *.dfm}

procedure TfrmProveedoresEditor.Loaded;
begin
  inherited Loaded;
  OnShow := FormShow;
end;

procedure TfrmProveedoresEditor.FormShow(Sender: TObject);
begin
  // Tema estándar
  TAppTheme.ApplyToForm(Self);

  // Vincular eventos a la barra superior heredada
  btnGuardar.OnClick := btnSaveClick;
  btnSalir.OnClick := btnSalirClick;

  // Ocultar componentes heredados innecesarios para mantenimiento simple
  pgcDetails.Visible := True;
  TsListado.TabVisible := False;
  pgcDetails.ActivePage := tsDatosEnvio;
  pnlSideToolbar.Visible := False;
  dbgItems.Visible := False;
  pnlFooter.Visible := False;
  lblCodigo.Visible := True;
  edtId.Visible := True;

  if FProveedorId <> '' then
    LoadData
  else
    DoAnadir;
end;

procedure TfrmProveedoresEditor.FormDestroy(Sender: TObject);
begin
  // No-op
end;

procedure TfrmProveedoresEditor.LoadData;
var
  Qry: TFDQuery;
begin
  if FProveedorId = '' then Exit;

  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := dmgMain.dbConn;
    Qry.SQL.Text := 'SELECT * FROM ge_proveedores WHERE id = :id';
    Qry.ParamByName('id').AsString := FProveedorId;
    Qry.Open;
    
    if not Qry.IsEmpty then
    begin
      edtId.Text := Qry.FieldByName('id').AsString;
      edtNIF.Text := Qry.FieldByName('nif').AsString;
      edtNombre.Text := Qry.FieldByName('nombre').AsString;
      edtDireccion.Text := Qry.FieldByName('direccion').AsString;
      edtCodigoPostal.Text := Qry.FieldByName('codigo_postal').AsString;
      edtPoblacion.Text := Qry.FieldByName('poblacion').AsString;
      edtProvincia.Text := Qry.FieldByName('provincia').AsString;
      edtTelefono1.Text := Qry.FieldByName('telefono_1').AsString;
      edtTelefono2.Text := Qry.FieldByName('telefono_2').AsString;
      edtEmail.Text := Qry.FieldByName('email').AsString;
      edtContacto.Text := Qry.FieldByName('contacto').AsString;
      edtObservaciones.Text := Qry.FieldByName('observaciones').AsString;
      chkActivo.Checked := Qry.FieldByName('activo').AsInteger <> 0;
      if SameText(Qry.FieldByName('tipo').AsString, 'SERVICIOS') then
        cbTipo.ItemIndex := 1
      else
        cbTipo.ItemIndex := 0;
    end;
  finally
    Qry.Free;
  end;

  // Cargar consultas dinámicas si están asignadas
  if Assigned(qArticulos) then
  begin
    qArticulos.Close;
    qArticulos.SQL.Text := 'SELECT pm.id, pm.codigo_articulo_proveedor as codigo, pm.descripcion, pm.id_materia_prima as id_propio, mp.descripcion as descripcion_propia, pm.ult_precio as precio, pm.activo ' +
                           'FROM ge_proveedores_materias_primas pm ' +
                           'LEFT JOIN ge_materias_primas mp ON pm.id_materia_prima = mp.id ' +
                           'WHERE pm.id_proveedor = :idproveedor ORDER BY pm.descripcion';
    qArticulos.ParamByName('idproveedor').AsInteger := StrToIntDef(FProveedorId, 0);
    qArticulos.Open;
  end;

  if Assigned(qAlbaranes) then
  begin
    qAlbaranes.Close;
    qAlbaranes.SQL.Text := 'SELECT id, documento, fecha, base, totaliva, totalentrada ' +
                           'FROM ge_prov_albaranes WHERE idproveedor = :idproveedor ORDER BY fecha DESC';
    qAlbaranes.ParamByName('idproveedor').AsInteger := StrToIntDef(FProveedorId, 0);
    qAlbaranes.Open;
  end;

  if Assigned(qFacturas) then
  begin
    qFacturas.Close;
    qFacturas.SQL.Text := 'SELECT id, documento, fecha, base, totaliva, totalentrada ' +
                           'FROM ge_prov_facturas WHERE idproveedor = :idproveedor ORDER BY fecha DESC';
    qFacturas.ParamByName('idproveedor').AsInteger := StrToIntDef(FProveedorId, 0);
    qFacturas.Open;
  end;
end;

procedure TfrmProveedoresEditor.DoAnadir;
begin
  FProveedorId := '';
  edtId.Clear;
  edtNIF.Clear;
  edtNombre.Clear;
  edtDireccion.Clear;
  edtCodigoPostal.Clear;
  edtPoblacion.Clear;
  edtProvincia.Clear;
  edtTelefono1.Clear;
  edtTelefono2.Clear;
  edtEmail.Clear;
  edtContacto.Clear;
  edtObservaciones.Clear;
  chkActivo.Checked := True;
  cbTipo.ItemIndex := 0;

  if Assigned(qArticulos) then qArticulos.Close;
  if Assigned(qAlbaranes) then qAlbaranes.Close;
  if Assigned(qFacturas) then qFacturas.Close;

  edtNombre.SetFocus;
end;

procedure TfrmProveedoresEditor.DoModificar;
begin
  edtNombre.SetFocus;
end;

procedure TfrmProveedoresEditor.DoPrimero;
var
  LParent: TfrmProveedoresList;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmProveedoresList) then
    LParent := TfrmProveedoresList(FParentForm)
  else if Assigned(frmProveedoresList) then
    LParent := frmProveedoresList;

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

procedure TfrmProveedoresEditor.DoAnterior;
var
  LParent: TfrmProveedoresList;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmProveedoresList) then
    LParent := TfrmProveedoresList(FParentForm)
  else if Assigned(frmProveedoresList) then
    LParent := frmProveedoresList;

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

procedure TfrmProveedoresEditor.DoSiguiente;
var
  LParent: TfrmProveedoresList;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmProveedoresList) then
    LParent := TfrmProveedoresList(FParentForm)
  else if Assigned(frmProveedoresList) then
    LParent := frmProveedoresList;

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

procedure TfrmProveedoresEditor.DoUltimo;
var
  LParent: TfrmProveedoresList;
begin
  LParent := nil;
  if Assigned(FParentForm) and (FParentForm is TfrmProveedoresList) then
    LParent := TfrmProveedoresList(FParentForm)
  else if Assigned(frmProveedoresList) then
    LParent := frmProveedoresList;

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

procedure TfrmProveedoresEditor.btnSalirClick(Sender: TObject);
begin
  ModalResult := mrCancel;
  Close;
end;

procedure TfrmProveedoresEditor.btnSaveClick(Sender: TObject);
var
  LIsNew: Boolean;
  LTipoDoc: TTipoDocumento;
  LNif: string;
begin
  if Trim(edtNombre.Text) = '' then
  begin
    ShowMessage('El nombre del proveedor es obligatorio.');
    edtNombre.SetFocus;
    Exit;
  end;

  if Trim(edtNIF.Text) = '' then
  begin
    ShowMessage('El NIF del proveedor es obligatorio.');
    edtNIF.SetFocus;
    Exit;
  end;

  // Validación del dígito de control (no bloqueante: avisa pero permite guardar)
  LNif := Trim(edtNIF.Text);
  if not TValidacionFiscal.ValidarDocumento(LNif, LTipoDoc) then
  begin
    if MessageDlg(
      'El NIF/CIF "' + LNif + '" no supera la validación del dígito de control.' + sLineBreak +
      '¿Desea guardarlo igualmente?',
      mtWarning, [mbYes, mbNo], 0) = mrNo then
    begin
      edtNIF.SetFocus;
      Exit;
    end;
  end;

  LIsNew := (FProveedorId = '');

  try
    dmgMain.qryExec.Close;
    if LIsNew then
    begin
      dmgMain.qryExec.SQL.Text :=
        'INSERT INTO ge_proveedores (nif, nombre, direccion, codigo_postal, poblacion, ' +
        'provincia, telefono_1, telefono_2, email, contacto, observaciones, activo, tipo, id_user_creator, id_user_update) ' +
        'VALUES (:nif, :nom, :dir, :cp, :pob, :prov, :tel1, :tel2, :email, :cont, :obs, :act, :tipo, :user, :user)';
    end
    else
    begin
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_proveedores SET nif = :nif, nombre = :nom, direccion = :dir, ' +
        'codigo_postal = :cp, poblacion = :pob, provincia = :prov, telefono_1 = :tel1, telefono_2 = :tel2, ' +
        'email = :email, contacto = :cont, observaciones = :obs, activo = :act, tipo = :tipo, id_user_update = :user, updated_at = CURRENT_TIMESTAMP ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id').AsString := FProveedorId;
    end;

    dmgMain.qryExec.ParamByName('nif').AsString := Trim(edtNIF.Text);
    dmgMain.qryExec.ParamByName('nom').AsString := Trim(edtNombre.Text);
    dmgMain.qryExec.ParamByName('dir').AsString := Trim(edtDireccion.Text);
    dmgMain.qryExec.ParamByName('cp').AsString := Trim(edtCodigoPostal.Text);
    dmgMain.qryExec.ParamByName('pob').AsString := Trim(edtPoblacion.Text);
    dmgMain.qryExec.ParamByName('prov').AsString := Trim(edtProvincia.Text);
    dmgMain.qryExec.ParamByName('tel1').AsString := Trim(edtTelefono1.Text);
    dmgMain.qryExec.ParamByName('tel2').AsString := Trim(edtTelefono2.Text);
    dmgMain.qryExec.ParamByName('email').AsString := Trim(edtEmail.Text);
    dmgMain.qryExec.ParamByName('cont').AsString := Trim(edtContacto.Text);
    dmgMain.qryExec.ParamByName('obs').AsString := Trim(edtObservaciones.Text);
    dmgMain.qryExec.ParamByName('act').AsBoolean := chkActivo.Checked;
    dmgMain.qryExec.ParamByName('tipo').AsString := cbTipo.Text;
    dmgMain.qryExec.ParamByName('user').AsString := dmgMain.CurrentUserId;

    dmgMain.qryExec.ExecSQL;
    ResetChangeTracking;
    if Assigned(FParentForm) and (FParentForm is TfrmProveedoresList) then
      TfrmProveedoresList(FParentForm).btnRefreshClick(nil);
    ShowMessage('Proveedor guardado correctamente.');
  except
    on E: Exception do
      TDbErrorHandler.HandleException(E, 'Error al guardar el proveedor');
  end;
end;

procedure TfrmProveedoresEditor.dbgArticulosDblClick(Sender: TObject);
begin
  if not qArticulos.Active or qArticulos.IsEmpty then Exit;

  if not Assigned(frmAsignarMateriasPrimas) then
    Application.CreateForm(TfrmAsignarMateriasPrimas, frmAsignarMateriasPrimas);
  
  frmAsignarMateriasPrimas.SelectedCatalogId := qArticulos.FieldByName('id').AsInteger;
  frmAsignarMateriasPrimas.ShowModal;
  LoadData;
end;

procedure TfrmProveedoresEditor.dbgAlbaranesDblClick(Sender: TObject);
begin
  if not qAlbaranes.Active or qAlbaranes.IsEmpty then Exit;
  if not qAlbaranes.FieldByName('id').IsNull then
  begin
    if not Assigned(frmProvAlbaranesEditor) then
      Application.CreateForm(TfrmProvAlbaranesEditor, frmProvAlbaranesEditor);
    
    frmProvAlbaranesEditor.qMaster.Close;
    frmProvAlbaranesEditor.qMaster.SQL.Text := 
      'SELECT f.*, p.nombre as nombre_proveedor FROM ge_prov_albaranes f ' +
      'LEFT JOIN ge_proveedores p ON f.idproveedor = p.id ' +
      'WHERE f.idempresa = :idempresa ORDER BY f.fecha DESC, f.documento DESC';
    frmProvAlbaranesEditor.qMaster.ParamByName('idempresa').AsString := dmgMain.CurrentCompanyId;
    frmProvAlbaranesEditor.qMaster.Open;
    if frmProvAlbaranesEditor.qMaster.Locate('id', qAlbaranes.FieldByName('id').AsString, []) then
    begin
      if frmProvAlbaranesEditor.ShowModal = mrOk then
        LoadData;
    end;
  end;
end;

procedure TfrmProveedoresEditor.dbgFacturasDblClick(Sender: TObject);
begin
  if not qFacturas.Active or qFacturas.IsEmpty then Exit;
  if not qFacturas.FieldByName('id').IsNull then
  begin
    if not Assigned(frmProvFacturasEditor) then
      Application.CreateForm(TfrmProvFacturasEditor, frmProvFacturasEditor);
    
    frmProvFacturasEditor.qMaster.Close;
    frmProvFacturasEditor.qMaster.SQL.Text := 
      'SELECT f.*, p.nombre as nombre_proveedor FROM ge_prov_facturas f ' +
      'LEFT JOIN ge_proveedores p ON f.idproveedor = p.id ' +
      'WHERE f.idempresa = :idempresa ORDER BY f.fecha DESC, f.documento DESC';
    frmProvFacturasEditor.qMaster.ParamByName('idempresa').AsString := dmgMain.CurrentCompanyId;
    frmProvFacturasEditor.qMaster.Open;
    if frmProvFacturasEditor.qMaster.Locate('id', qFacturas.FieldByName('id').AsString, []) then
    begin
      if frmProvFacturasEditor.ShowModal = mrOk then
        LoadData;
    end;
  end;
end;

end.
