# app/helpers/application_helper.rb
module ApplicationHelper
  include Pagy::Frontend

  # ---------------------------------------------------------------------------
  # Ícones
  #
  # Substituem os emojis antigos (que davam aparência "genérica de IA" e variavam
  # de forma/cor conforme o sistema operacional). Agora são SVG chapados vindos do
  # sprite em public/icons.svg (subset do Bootstrap Icons, licença MIT).
  #
  # O SVG usa `currentColor`, então a cor vem da classe CSS:
  #   - padrão              → laranja da marca (#f97316)
  #   - ícones de status    → passe `cor:` para preservar a leitura semântica
  #                           (ex.: icone(:sucesso, cor: "text-green-400"))
  # ---------------------------------------------------------------------------

  # Nome semântico (pt-BR) → id do símbolo no sprite.
  ICONES = {
    # Navegação
    dashboard: "bar-chart-fill",   operacoes: "graph-up-arrow",  consolidacoes: "box-seam-fill",
    arquivadas: "folder-fill",     painel: "house-fill",         usuarios: "people-fill",
    configuracoes: "gear-fill",    auditoria: "search",          planilha: "box-arrow-in-down",
    editar_lancamento: "pencil-fill", sair: "box-arrow-right",   menu: "list",
    # Domínio
    caminhao: "truck",             veiculo: "car-front-fill",    motorista: "person-badge-fill",
    dinheiro: "cash-coin",         pagamento: "cash-stack",      custo: "cash",
    consolidado_pago: "briefcase-fill", calendario: "calendar-event", nota_fiscal: "receipt",
    documento: "file-earmark-text-fill", termo_especial: "clipboard-data-fill",
    apontamento: "pencil-square",  local: "geo-alt-fill",        operacao: "hospital-fill",
    retirada: "box-seam-fill",     desconto: "exclamation-triangle-fill",
    global: "globe2",              comparar: "arrow-left-right", pessoa: "person-fill",
    ticket: "ticket-perforated-fill", tag: "tag-fill",           composicao: "puzzle-fill",
    ranking: "trophy-fill",        historico: "clock-history",   relogio: "clock-fill",
    parcial: "hourglass-split",    diario: "journal-text",       vazio: "inbox",
    dica: "lightbulb-fill",        bonus: "star-fill",           extraordinaria: "stars",
    calor: "fire",                 foto: "camera-fill",          mapa: "map-fill",
    satelite: "broadcast-pin",     escuro: "moon-fill",          tela_cheia: "arrows-fullscreen",
    email: "envelope-fill",        telefone: "telephone-fill",   chave: "key-fill",
    # Ações
    adicionar: "plus-lg",          fechar: "x-lg",               confirmar: "check-lg",
    buscar: "search",              editar: "pencil-fill",        excluir: "trash-fill",
    arquivar: "archive-fill",      restaurar: "arrow-clockwise", salvar: "floppy-fill",
    imprimir: "printer-fill",      visualizar: "eye-fill",       baixar: "download",
    pasta: "folder2-open",         travado: "lock-fill",         destravado: "unlock-fill",
    expandir: "chevron-down",      recolher: "chevron-left",
    voltar: "arrow-left",          avancar: "arrow-right",       estornar: "arrow-counterclockwise",
    # Status (use sempre com `cor:` semântica)
    sucesso: "check-circle-fill",  alerta: "exclamation-triangle-fill",
    erro: "x-circle-fill",         desconhecido: "question-circle",
    cancelado: "slash-circle",     ponto: "circle-fill",         ponto_vazio: "circle"
  }.freeze

  # Renderiza um ícone do sprite.
  #
  #   icone(:caminhao)                          # laranja da marca
  #   icone(:sucesso, cor: "text-green-400")    # status verde
  #   icone(:fechar, cor: nil)                  # herda a cor do elemento pai
  #   icone(:dashboard, titulo: "Painel")       # acessível (vira role="img")
  #   icone(:fechar, espaco: false)             # sem margem (ícone sozinho/centralizado)
  #
  # ATENÇÃO — contraste: em fundo LARANJA (bg-orange-*, bg-[#f97316]) o laranja
  # padrão fica invisível. Nesses casos passe `cor: nil` (herda a cor do texto do
  # container) ou `cor: "text-black"`.
  #
  # `espaco:` acrescenta uma margem à direita para o ícone não colar no texto.
  # Desligue (`espaco: false`) quando o ícone estiver sozinho ou centralizado —
  # senão a margem o tira do eixo — ou quando o container já tiver `gap-*`.
  def icone(nome, cor: "text-brand-laranja", tamanho: "w-[1.25em] h-[1.25em]",
            classe: nil, titulo: nil, espaco: true)
    simbolo = ICONES.fetch(nome.to_sym) { nome.to_s }
    css = ["inline-block align-[-0.125em] shrink-0", ("mr-1" if espaco),
           tamanho, cor, classe].compact.join(" ")

    tag.svg(class: css, fill: "currentColor", role: (titulo ? "img" : nil),
            aria: { hidden: (titulo ? nil : true), label: titulo }) do
      tag.use(href: "/icons.svg##{simbolo}")
    end
  end

  # Rótulo "ícone + texto" para link_to / button_to (que recebem o label como
  # argumento, onde não dá para escrever ERB).
  #
  #   link_to rotulo(:salvar, 'Salvar rascunho'), caminho, class: '...'
  #
  # Atenção: NÃO serve para `f.submit` nem `button_to` sem bloco — ambos geram
  # <input type="submit">, que não aceita HTML dentro. Nesses casos use
  # `button_tag`/`button_to ... do`.
  def rotulo(nome, texto, cor: "text-brand-laranja", tamanho: "w-5 h-5")
    # O espaçamento vem do `mr-1` do próprio ícone (ver `icone`).
    safe_join([icone(nome, cor: cor, tamanho: tamanho), texto])
  end

  # Opções [label, valor] para o select de perfil de usuário (form de usuário)
  def role_options_for_select
    User::ROLES_LABEL.map { |value, label| [label, value] }
  end

  # Link de navegação com estado ativo.
  # `icon:` aceita um nome semântico de ICONES; no estado ativo o ícone herda o
  # preto do fundo laranja, fora dele fica laranja da marca.
  def nav_link_to(label, path, icon: nil, **opts)
    active = current_page?(path)
    css = [
      "flex items-center gap-2.5 px-3 py-2.5 rounded-lg text-sm font-medium transition-all min-h-[44px]",
      active ? "bg-orange-500 text-black" : "text-gray-400 hover:bg-[#1a1a1a] hover:text-white"
    ].join(" ")

    conteudo = if icon
                 safe_join([icone(icon, cor: (active ? "text-black" : "text-brand-laranja"),
                                        tamanho: "w-5 h-5", espaco: false), label])
               else
                 label
               end
    link_to conteudo, path, class: css
  end

  # Formata moeda BR (milhar com ".", decimais com ","): R$ 1.234,56
  def moeda(valor)
    number_to_currency(valor.to_f, unit: 'R$ ', separator: ',', delimiter: '.', precision: 2)
  end

  # Badge de status de consolidação.
  # O ícone herda a cor do texto do badge (cor: nil) para não brigar com o fundo.
  def badge_status(status)
    cfg = case status.to_s
          when 'rascunho'   then { cor: 'bg-yellow-500 text-black', icone: :apontamento, label: 'Rascunho' }
          when 'finalizada' then { cor: 'bg-green-600 text-white',  icone: :sucesso,     label: 'Finalizada' }
          when 'arquivada'  then { cor: 'bg-gray-700 text-gray-300', icone: :arquivar,   label: 'Arquivada' }
          else                   { cor: 'bg-gray-800 text-gray-400', icone: :desconhecido, label: status.humanize }
          end

    badge_com_icone(cfg)
  end

  # Badge de status de pagamento de uma consolidação (derivado dos motoristas)
  def badge_pagamento(status)
    cfg = case status.to_s
          when 'pago'     then { cor: 'bg-green-600 text-white',     icone: :dinheiro, label: 'Pago' }
          when 'parcial'  then { cor: 'bg-yellow-500 text-black',    icone: :parcial,  label: 'Parcial' }
          when 'pendente' then { cor: 'bg-gray-700 text-gray-300',   icone: :relogio,  label: 'Pendente' }
          else                 { cor: 'bg-gray-800 text-gray-400',   icone: :desconhecido, label: status.to_s.humanize }
          end

    badge_com_icone(cfg)
  end

  def badge_com_icone(cfg)
    tag.span class: "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold #{cfg[:cor]}" do
      safe_join([icone(cfg[:icone], cor: nil, tamanho: "w-4 h-4", espaco: false), cfg[:label]])
    end
  end

  # Badge de papel do usuário (admin/gerente/operador/motorista)
  def badge_role(role)
    cfg = case role.to_s
          when 'admin'     then { cor: 'bg-orange-500 text-black' }
          when 'gerente'   then { cor: 'bg-orange-800 text-white' }
          when 'operador'  then { cor: 'bg-gray-700 text-white' }
          when 'motorista' then { cor: 'bg-gray-900 text-orange-400 border border-orange-500' }
          when 'externo'   then { cor: 'bg-blue-900 text-blue-200 border border-blue-500' }
          else                  { cor: 'bg-gray-800 text-gray-400' }
          end
    label = User::ROLES_LABEL[role.to_s] || role.to_s.humanize

    tag.span label, class: "inline-flex items-center px-2.5 py-1 rounded-full text-xs font-bold #{cfg[:cor]}"
  end

  # Badge de status ativo/inativo do usuário
  def badge_status_usuario(ativo)
    cor   = ativo ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
    label = ativo ? 'Ativo' : 'Inativo'
    tag.span label, class: "inline-flex items-center px-2.5 py-1 rounded-full text-xs font-bold #{cor}"
  end

  # Horário da última sincronização dos dados de operação.
  #
  # O backend atualiza os dados a cada 30 min, das 08h às 18h (horário de
  # Brasília). Como as tabelas externas de rastreio não têm um carimbo de
  # sincronização confiável, derivamos o último "slot" concluído a partir dessa
  # grade fixa. Usa Time.current (fuso do app), NUNCA Time.now — que pega o fuso
  # do container (UTC) e por isso mostrava o horário adiantado/errado.
  DADOS_SYNC_INICIO = 8   # abre às 08h
  DADOS_SYNC_FIM    = 18  # fecha às 18h
  DADOS_SYNC_PASSO  = 30  # minutos entre atualizações

  def ultima_atualizacao_dados(agora = Time.current)
    agora = agora.in_time_zone
    abre  = agora.change(hour: DADOS_SYNC_INICIO, min: 0)
    fecha = agora.change(hour: DADOS_SYNC_FIM,    min: 0)

    if agora < abre
      # Antes de abrir: a última atualização foi o fechamento do dia anterior.
      (abre - 1.day).change(hour: DADOS_SYNC_FIM, min: 0)
    elsif agora >= fecha
      fecha
    else
      # Arredonda para baixo ao múltiplo de 30 min dentro da janela.
      minuto = (agora.min / DADOS_SYNC_PASSO) * DADOS_SYNC_PASSO
      agora.change(min: minuto, sec: 0)
    end
  end

  # Rótulo amigável: "às 14:30" (hoje) ou "em 05/07 às 18:00" (outro dia).
  def ultima_atualizacao_label(agora = Time.current)
    t = ultima_atualizacao_dados(agora)
    if t.to_date == agora.in_time_zone.to_date
      "às #{t.strftime('%H:%M')}"
    else
      "em #{t.strftime('%d/%m')} às #{t.strftime('%H:%M')}"
    end
  end

  # Barra de progresso laranja
  def progress_bar(percentual, label: nil)
    pct = percentual.to_i.clamp(0, 100)
    tag.div class: "w-full" do
      concat tag.div(class: "flex justify-between text-xs text-gray-400 mb-1") {
        concat tag.span(label || "#{pct}% classificado")
        concat tag.span("#{pct}%")
      }
      concat tag.div(class: "w-full bg-[#2a2a2a] rounded-full h-2") {
        tag.div style: "width: #{pct}%",
                class: "h-2 rounded-full bg-orange-500 transition-all duration-500"
      }
    end
  end
end
