# app/services/romaneios/normalizador.rb
#
# Parsing compartilhado entre as duas fontes de plano (API e .xlsx). Existe para os
# dois caminhos entregarem EXATAMENTE a mesma forma de linha ao Romaneios::Importador
# — se cada um normalizasse do seu jeito, o mesmo plano importado por caminhos
# diferentes geraria linhas com chave_origem diferente e a reconciliação duplicaria
# tudo na primeira reimportação.
#
# Namespace no plural (Romaneios::) para não colidir com a constante do model
# Romaneio.
module Romaneios
  module Normalizador
    # "NF 90507 - CICERA BESERRA DOS ANJOS" -> ['90507', 'CICERA BESERRA DOS ANJOS']
    NF_TITULO = /\ANF\s+(\d+)\s*-\s*(.+)\z/i

    # "TEL: (11) 99262-0594 / (11) 99824-8099" — o plano guarda o telefone dentro
    # das Anotações, em texto livre. Pegamos TODOS os que casarem: uma parada com
    # dois números precisa dos dois no papel (o motorista liga do portão).
    TEL_ANOTACAO = /\(?\d{2}\)?\s*\d{4,5}-?\d{4}/

    module_function

    # Devolve [nf, nome]. Título fora do padrão vira [nil, título] — não é erro:
    # plano avulso e de inclusão às vezes chegam sem o prefixo "NF n - ".
    def nf_e_nome(titulo)
      texto = titulo.to_s.strip
      m = NF_TITULO.match(texto)
      return [m[1], m[2].strip] if m

      [nil, texto]
    end

    # O SimpliRoute devolve o endereço com sufixo ", Brazil"; o documento impresso
    # nunca teve isso. Caixa alta porque é como o romaneio sai desde sempre.
    def endereco(valor)
      valor.to_s
           .gsub(/,\s*Brazil\s*\z/i, '')
           .strip
           .gsub(/\s+/, ' ')
           .upcase
    end

    # Telefones a partir das anotações do plano. Só é usado quando a operação não
    # tem o número — a coluna `telefones` da gade_entregas_* é a fonte preferida
    # (ver Romaneios::EnriquecimentoGade).
    def telefones_de_anotacao(anotacoes)
      texto = anotacoes.to_s
      return '' unless texto.match?(/TEL/i)

      texto.scan(TEL_ANOTACAO).map(&:strip).uniq.join(' / ')
    end

    def nome(valor)
      valor.to_s.strip.gsub(/\s+/, ' ').upcase
    end

    # 'SIM' quando o paciente é NOVO na operação; vazio caso contrário.
    # É o que a segunda planilha do programa Python fazia à mão.
    def aparelho_por_status(status_gade)
      status_gade.to_s.strip.casecmp('NOVO').zero? ? 'SIM' : ''
    end

    # Uma linha crua do plano (de qualquer fonte) vira a forma canônica que o
    # Importador consome.
    def linha(veiculo:, ordem:, titulo:, endereco:, anotacoes: nil,
              nota_fiscal: nil, tracking_id: nil, motorista: nil)
      # `endereco` aqui é a variável local do kwarg — o método homônimo continua
      # acessível com parênteses, mas renomeamos para ninguém tropeçar.
      endereco_cru = endereco
      nf_titulo, nome_titulo = nf_e_nome(titulo)
      nf = nota_fiscal.to_s.strip
      nf = nf_titulo.to_s if nf.empty?

      {
        veiculo:     veiculo.to_s.strip,
        ordem:       ordem.to_i,
        motorista:   motorista.to_s.strip,
        nota_fiscal: nf.to_s,
        nome:        nome(nome_titulo),
        endereco:    endereco(endereco_cru),
        telefones:   telefones_de_anotacao(anotacoes),
        tracking_id: tracking_id.to_s,
        titulo:      titulo.to_s
      }
    end
  end
end
