# app/services/notificacao/whatsapp.rb
#
# Ponto ÚNICO de envio de WhatsApp: escolhe o provedor configurado e devolve
# sempre a mesma resposta, venha de onde vier.
#
# Existe para que trocar Twilio ↔ Baileys seja um campo na tela, e não um `if`
# espalhado por cada chamador. O NotificacaoService (aviso ao motorista) e o
# Despachante (grupos) passam os dois por aqui.
module Notificacao
  module Whatsapp
    Resposta = ClienteWhatsapp::Resposta

    def self.enviar(para:, texto:, config: ConfiguracaoNotificacao.instancia)
      # Grupo do WhatsApp vem como JID pronto ("120363...@g.us") — não é
      # telefone, não normaliza. Passa direto para a ponte, que aceita as duas
      # formas.
      if Contato::JID_GRUPO_RE.match?(para.to_s.strip)
        return Resposta.new(ok: false, erro: 'O Twilio não envia para grupo do WhatsApp. ' \
                                             'Troque o provedor para QR code.') unless config.baileys?

        return via_baileys(para.to_s.strip, texto)
      end

      destino = ConfiguracaoNotificacao.normalizar_telefone(para)
      return Resposta.new(ok: false, erro: 'Número inválido.') if destino.blank?

      config.baileys? ? via_baileys(destino, texto) : via_twilio(destino, texto, config)
    end

    def self.via_baileys(destino, texto)
      ClienteWhatsapp.padrao.enviar(para: destino, texto: texto)
    end

    def self.via_twilio(destino, texto, config)
      credenciais = config.credenciais_whatsapp
      if credenciais.blank? || credenciais[:from].blank?
        return Resposta.new(ok: false, erro: 'Twilio sem credenciais configuradas.')
      end

      ClienteTwilio.montar(credenciais[:sid], credenciais[:token])
                   .messages.create(from: credenciais[:from],
                                    to: ConfiguracaoNotificacao.canal(destino),
                                    body: texto)
      Resposta.new(ok: true)
    rescue StandardError => e
      # Falha de envio nunca pode subir: quem chama está no meio de um
      # fechamento de pagamento.
      Resposta.new(ok: false, erro: "#{e.class}: #{e.message}")
    end
  end
end
