# Harness de uma tabela de operação (gade_entregas_*) para os specs.
#
# A tabela é EXTERNA: não tem migration (o cliente a carrega no banco) e não tem
# factory. Sem este harness, testar o enriquecimento do romaneio só daria para
# mockar o método sob teste — o que não pega regressão de SQL, que é onde moram os
# bugs de coluna ausente e de alias (`status` da gade x `status` do espelho).
#
# Guardas copiadas de spec/support/espelho_rastreio.rb, pelo mesmo motivo: se a
# tabela já existir COM DADOS, estamos apontados para dados de verdade e o spec tem
# que abortar em vez de destruí-los.
#
# Uso:
#
#   RSpec.describe Romaneios::EnriquecimentoGade do
#     include_context 'tabela de operação'
#
#     it '...' do
#       criar_operacao!('gade_entregas_teste_jan_2026', colunas: %i[nome_completo telefones status])
#       semear_operacao!('gade_entregas_teste_jan_2026', [{ nota_fiscal: '1', status: 'NOVO' }])
#     end
#   end
module TabelaOperacao
  COLUNAS_PADRAO = %i[nome_completo telefones status].freeze

  class << self
    def criar!(nome, colunas: COLUNAS_PADRAO)
      raise "Tabela de operação de teste exige RAILS_ENV=test (está em #{Rails.env})" unless Rails.env.test?

      if conexao.table_exists?(nome)
        linhas = conexao.select_value("SELECT COUNT(*) FROM #{conexao.quote_table_name(nome)}").to_i
        if linhas.positive?
          raise "#{nome} já existe no banco de teste com #{linhas} linha(s) — o spec NÃO vai " \
                'derrubá-la. Aponte RAILS_ENV=test para um banco descartável.'
        end
        conexao.drop_table(nome)
      end

      conexao.create_table(nome, id: false) do |t|
        t.string :nota_fiscal
        colunas.each { |c| t.string c }
      end
      criadas << nome
      nome
    end

    def semear!(nome, linhas)
      colunas = conexao.columns(nome).map(&:name)
      linhas.each do |linha|
        dados = linha.transform_keys(&:to_s).slice(*colunas)
        conexao.execute(
          "INSERT INTO #{conexao.quote_table_name(nome)} (#{dados.keys.join(', ')}) " \
          "VALUES (#{dados.values.map { |v| conexao.quote(v) }.join(', ')})"
        )
      end
    end

    def derrubar_todas!
      criadas.each { |nome| conexao.drop_table(nome, if_exists: true) }
      criadas.clear
    end

    def criadas
      @criadas ||= []
    end

    private

    def conexao
      ActiveRecord::Base.connection
    end
  end
end

RSpec.shared_context 'tabela de operação' do
  after { TabelaOperacao.derrubar_todas! }

  def criar_operacao!(nome, colunas: TabelaOperacao::COLUNAS_PADRAO)
    TabelaOperacao.criar!(nome, colunas: colunas)
  end

  def semear_operacao!(nome, linhas)
    TabelaOperacao.semear!(nome, linhas)
  end
end
