# typed: true
# frozen_string_literal: true

module HasAuxTable
  module Util
    extend T::Sig

    sig do
      params(
        target:
          T.any(
            T.class_of(ActiveRecord::Base),
            T.class_of(ActiveRecord::Relation)
          ),
        method_name: Symbol,
        is_instance_method: T::Boolean,
        hook_block: T.proc.params(args: T.untyped).void
      ).void
    end
    def self.hook_method(target, method_name, is_instance_method, &hook_block)
      define_method =
        is_instance_method ? :define_method : :define_singleton_method

      target_method =
        (
          if is_instance_method
            target.instance_method(method_name)
          else
            target.method(method_name)
          end
        )

      target.send(define_method, method_name) do |*args, **kwargs, &block|
        method = is_instance_method ? target_method.bind(self) : target_method
        T.unsafe(hook_block).call(method, *args, **kwargs, &block)
      end
    end

    # sig do
    #   type_parameters(:T)
    #     .params(
    #       obj: T::Class[T.type_parameter(:T)],
    #       name: Symbol,
    #       block: T.proc.bind(:T).void
    #     )
    #     .returns(Symbol)
    # end
    # def self.safe_define_method(obj, name, &block)
    # end

    # sig do
    #   type_parameters(:T)
    #     .params(
    #       obj: T::Class[T.type_parameter(:T)],
    #       name: Symbol,
    #       block: T.proc.bind(T.attached_class).void
    #     )
    #     .returns(Symbol)
    # end
    # def self.safe_define_singleton_method(obj, name, &block)
    #   Module.safe_define_singleton_method(name, &block)
    # end
  end
end
