# typed: true
# frozen_string_literal: true

module HasAuxTable
  class BaseTableDefinition
    delegate_missing_to :inner

    def initialize(schema, base_table_name, inner)
      @schema = schema
      @base_table_name = base_table_name
      @inner = inner
    end

    def create_aux(aux_name, **options, &block)
      @schema.create_aux_table(@base_table_name, aux_name, **options, &block)
    end

    private

    attr_reader :schema, :inner
  end

  module MigrationExtensions
    extend T::Sig
    extend T::Helpers
    requires_ancestor { ActiveRecord::Migration }

    def create_base_table(name, type: :string, **options)
      create_table(name, **options) do |t|
        t.column :type, type, null: false
        t = BaseTableDefinition.new(self, name, t)
        yield t
      end
    end

    def change_base_table(name, **options)
      change_table(name, **options) do |t|
        yield BaseTableDefinition.new(self, name, t)
      end
    end

    def create_aux_table(base_table, name, **options)
      aux_table_name = "#{base_table}_#{name}_aux"
      create_table(aux_table_name, id: false, **options) do |t|
        t.references :base_table,
                     primary_key: true,
                     null: false,
                     foreign_key: {
                       to_table: base_table,
                       validate: true
                     }
        yield t
      end
    end
  end
end

class ActiveRecord::Migration
  include HasAuxTable::MigrationExtensions
end
