#!/usr/bin/env ruby
# frozen_string_literal: true
#
# Descobre COMO a API do SimpliRoute expõe o par veículo/ordem de um plano — que é
# o que o romaneio ("CONTROLE DE ENTREGA") precisa para saber quantas folhas
# imprimir e em que sequência.
#
# ── POR QUE ESTE SCRIPT EXISTE ──────────────────────────────────────────────
# Romaneios::PlanoDoDia tem uma escada de queda:
#   (a) /v1/routes/routes/ traz vehicle + lista ordenada de visitas
#   (b) a própria visita traz alguma chave de veículo/ordem
#   (c) nada disso -> espelho local (db_reem_simplerout_2026), por vehicle + eta
#   (d) espelho vazio -> manda o operador subir o .xlsx do plano
# As rungs (a) e (b) NUNCA foram verificadas: não há SIMPLIROUTE_TOKEN na máquina
# de desenvolvimento. Este script fecha isso.
#
# ── RESULTADO DA RODADA DE __/__/____ ───────────────────────────────────────
#   (preencher depois de rodar, como está em bin/sondar_busca_nf)
#   [ ] /v1/routes/routes/ existe?          status: ___   rotas: ___
#   [ ] a rota traz vehicle?                ___
#   [ ] a rota embute a lista de visitas?   ___
#   [ ] a visita traz vehicle/order?        ___
#   [ ] veículos pela API x pelo espelho:   ___ x ___
#   => rung usada: ___
#
# SÓ LEITURA: o script faz apenas GET. Não altera nada.
#
# Rode NO SERVIDOR (é lá que vive o SIMPLIROUTE_TOKEN):
#
#   SIMPLIROUTE_TOKEN=xxx bin/sondar_plano_do_dia --data 2026-08-31
#
# --data precisa ser um dia com plano PUBLICADO (senão a resposta vem vazia e não
# prova nada).
#
# ⚠️ Por que olhar os VALORES e não só as chaves: a API é Django REST e devolve
# chave existente com valor nil o tempo todo. "A visita tem a chave `vehicle`" NÃO
# significa que ela venha preenchida — a prova é o valor.

require 'net/http'
require 'json'
require 'uri'
require 'date'

BASE  = ENV.fetch('SIMPLIROUTE_BASE_URL', 'https://api.simpliroute.com')
TOKEN = ENV['SIMPLIROUTE_TOKEN'].to_s

CHAVES_INTERESSE = /vehicle|route|driver|order|sequence|position/i.freeze

def sair(msg)
  warn msg
  exit 1
end

sair('Defina SIMPLIROUTE_TOKEN no ambiente.') if TOKEN.empty?

data = nil
ARGV.each_with_index { |a, i| data = ARGV[i + 1] if a == '--data' }
sair('Uso: bin/sondar_plano_do_dia --data <YYYY-MM-DD>') if data.to_s.empty?
Date.parse(data) rescue sair("Data inválida: #{data}")

def get(caminho)
  uri = URI.join(BASE, caminho)
  req = Net::HTTP::Get.new(uri)
  req['Authorization'] = "Token #{TOKEN}"
  req['Accept'] = 'application/json'

  inicio = Time.now
  res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https',
                                            open_timeout: 10, read_timeout: 120) do |http|
    http.request(req)
  end
  [res.code.to_i, res.body.to_s, Time.now - inicio]
rescue StandardError => e
  [0, e.message, Time.now - inicio]
end

def json(corpo)
  JSON.parse(corpo)
rescue JSON::ParserError
  nil
end

def amostra(hash)
  hash.select { |k, _| k.to_s.match?(CHAVES_INTERESSE) }
      .map { |k, v| "  #{k} = #{v.inspect.slice(0, 90)}" }
end

puts "== SONDAGEM DO PLANO DE #{data} =="
puts

# ── 1. Visitas do dia ───────────────────────────────────────────────────────
codigo, corpo, seg = get("/v1/routes/visits/?planned_date=#{data}")
puts "[1] GET /v1/routes/visits/?planned_date=#{data}"
puts "    HTTP #{codigo} · #{corpo.bytesize} bytes · #{seg.round(2)}s"

visitas = json(corpo)
sair('    Resposta não é JSON — abortando.') unless visitas.is_a?(Array)
puts "    visitas: #{visitas.size}"
sair('    Nenhuma visita nessa data. Escolha um dia com plano publicado.') if visitas.empty?

primeira = visitas.first
puts "    chaves: #{primeira.keys.sort.join(', ')}"
puts '    chaves de interesse (com VALOR — chave nil não serve):'
linhas = amostra(primeira)
puts(linhas.empty? ? '      (nenhuma)' : linhas)

preenchidas = primeira.select { |k, v| k.to_s.match?(CHAVES_INTERESSE) && !v.nil? && v.to_s.strip != '' }
puts "    => rung (b) viável? #{preenchidas.keys.any? { |k| k.to_s.match?(/vehicle/i) } ? 'SIM' : 'NÃO'}"
puts

# ── 2. Rotas do dia ─────────────────────────────────────────────────────────
codigo, corpo, seg = get("/v1/routes/routes/?planned_date=#{data}")
puts "[2] GET /v1/routes/routes/?planned_date=#{data}"
puts "    HTTP #{codigo} · #{corpo.bytesize} bytes · #{seg.round(2)}s"

rotas = json(corpo)
if rotas.is_a?(Array) && rotas.any?
  rota = rotas.first
  puts "    rotas: #{rotas.size}"
  puts "    chaves: #{rota.keys.sort.join(', ')}"
  puts '    chaves de interesse:'
  puts(amostra(rota).then { |l| l.empty? ? '      (nenhuma)' : l })
  visits = rota['visits']
  puts "    embute 'visits'? #{visits.nil? ? 'NÃO' : "SIM (#{Array(visits).size} itens, #{Array(visits).first.class})"}"
  tem_veiculo = %w[vehicle vehicle_name vehicle_id].any? { |k| rota[k].to_s.strip != '' }
  puts "    => rung (a) viável? #{tem_veiculo && !visits.nil? ? 'SIM' : 'NÃO'}"
else
  puts "    sem rotas utilizáveis (corpo: #{corpo.slice(0, 200)})"
  puts '    => rung (a) NÃO viável'
end
puts

# ── 3. Cruzamento com o espelho ─────────────────────────────────────────────
# Quantos veículos a API enxerga? O número tem que bater com o do espelho local;
# se não bater, alguma rota está ficando de fora e o romaneio sairia incompleto.
veiculos_api = visitas.filter_map { |v| %w[vehicle vehicle_name].filter_map { |k| v[k] }.first }
                      .map(&:to_s).reject(&:empty?).uniq
if rotas.is_a?(Array)
  veiculos_api |= rotas.filter_map { |r| %w[vehicle vehicle_name].filter_map { |k| r[k] }.first }
                       .map(&:to_s).reject(&:empty?)
end
puts "[3] veículos distintos vistos pela API: #{veiculos_api.size}"
puts "    #{veiculos_api.sort.first(10).join(', ')}#{'…' if veiculos_api.size > 10}"
puts
puts '    Compare com o espelho, no console do app:'
puts "      Entrega.da_conta_gade.no_periodo(Date.parse('#{data}'), Date.parse('#{data}'))" \
     '.distinct.count(:vehicle)'
puts
puts 'Anote o resultado no cabeçalho deste arquivo antes de commitar.'
