require 'rails_helper'
# A gem entra com `require: false` no Gemfile (é ferramenta de teste, não de runtime).
require 'pdf/inspector'

# As constantes derivadas SÃO o contrato do documento: elas foram conferidas pixel a
# pixel contra Imagens para implantação/Romaneiro_EMAD_SETEMBRO_2026.pdf (render a
# 110 dpi). Se alguém mexer numa margem "só um pouquinho", é aqui que aparece.
RSpec.describe Pdf::RomaneioPdf do
  let(:romaneio) { create(:romaneio) }

  def semear(veiculo, quantidade)
    quantidade.times do |i|
      create(:romaneio_linha, romaneio: romaneio, veiculo: veiculo, ordem: i + 1)
    end
  end

  def paginas(pdf)
    PDF::Inspector::Page.analyze(pdf).pages.size
  end

  describe 'geometria' do
    subject(:documento) { described_class.new(romaneio: romaneio) }

    it 'é A4 paisagem' do
      medidas = documento.instance_variable_get(:@pdf).bounds
      expect([medidas.width.round(2), medidas.height.round(2)]).to eq([785.2, 487.56])
    end

    it 'mantém a altura de linha e os corpos de fonte do documento original' do
      expect(documento.instance_variable_get(:@linha_h)).to be_within(0.001).of(11.1811)
      expect(documento.instance_variable_get(:@fonte_dados)).to eq(7.0)
      expect(documento.instance_variable_get(:@fonte_hdr)).to eq(7.5)
    end

    it 'usa a largura útil inteira nas seis colunas' do
      larguras = documento.instance_variable_get(:@larguras)
      expect(larguras.size).to eq(6)
      expect(larguras.sum).to be_within(0.01).of(785.2)
    end

    it 'reserva espaço para o rodapé caber na folha cheia' do
      # 33 paradas + as 2 linhas em branco estouravam o orçamento e o
      # "ASSINATURA DO MOTORISTA" sumia do papel, sem erro nenhum.
      expect(documento.instance_variable_get(:@max_linhas_folha))
        .to be >= described_class::MAX_LINHAS
    end
  end

  it 'gera uma página por veículo' do
    semear('GADE_001', 5)
    semear('GADE_002', 3)

    expect(paginas(described_class.new(romaneio: romaneio).render)).to eq(2)
  end

  it 'imprime só o veículo pedido (é o que a prévia do editor usa)' do
    semear('GADE_001', 5)
    semear('GADE_002', 3)

    expect(paginas(described_class.new(romaneio: romaneio, veiculos: ['GADE_002']).render)).to eq(1)
  end

  it 'quebra em folhas de continuação acima de MAX_LINHAS' do
    semear('GADE_008', described_class::MAX_LINHAS + 1)

    pdf = described_class.new(romaneio: romaneio).render
    expect(paginas(pdf)).to eq(2)
    texto = PDF::Inspector::Text.analyze(pdf).strings.join(' ')
    expect(texto).to include('FOLHA 1/2').and include('FOLHA 2/2')
  end

  it 'assina TODAS as folhas — inclusive a de continuação' do
    semear('GADE_008', described_class::MAX_LINHAS + 1)

    texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings
    expect(texto.count { |t| t.include?('ASSINATURA DO MOTORISTA') }).to eq(2)
  end

  it 'numera as paradas continuando entre folhas (bate com a ordem no celular)' do
    semear('GADE_008', described_class::MAX_LINHAS + 1)

    texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings
    expect(texto).to include((described_class::MAX_LINHAS + 1).to_s)
  end

  it 'não imprime a parada que saiu do plano' do
    semear('GADE_001', 3)
    romaneio.romaneio_linhas.first.update!(removido_em: Time.current, nome: 'NAO DEVE SAIR')

    texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings.join(' ')
    expect(texto).not_to include('NAO DEVE SAIR')
  end

  it 'escreve o rótulo do plano no cabeçalho' do
    semear('GADE_001', 2)

    texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings.join(' ')
    expect(texto).to include('PLANO:').and include('EMAD 09.2026')
  end

  it 'aguenta acento nos endereços (a fonte AFM do Prawn estouraria aqui)' do
    create(:romaneio_linha, romaneio: romaneio, veiculo: 'GADE_001',
                            endereco: 'RUA INÁCIO DE OLIVEIRA CAMPOS, 182, SÃO PAULO')

    expect { described_class.new(romaneio: romaneio).render }.not_to raise_error
  end
end
