// app/javascript/controllers/validacao_controller.js
// Stimulus controller — Wizard Passo 2 (validação de entregas)
// Atualização em tempo real: toggles, ações em massa, barra de progresso, resumo lateral.

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [
    "linha", "checkbox", "selecionarTodos", "busca", "buscaVazia",
    "grupoPilares", "chipSelecao", "contadorSelecao", "btnLimpar",
    "resumo", "listaCol", "btnResumoLabel",
    "toggles", "barra", "barraManuais", "percentual", "chipVeiculo",
    "consolidarBtn", "consolidarHint",
    "contadorClassificadas", "contadorTotal", "contadorManuais", "manuaisInfo",
    "qtdNormal", "qtdRetirada", "qtdBonus", "qtdDesconto", "qtdExtraordinaria",
    "qtdTermo", "qtdTermoEspecial", "qtdManuais", "valorTotal"
  ]

  static values = {
    url:                 String,   // POST classificar
    massaUrl:            String,   // POST classificar_em_massa
    motorista:           String,
    total:               Number,
    veiculos:            Array,    // veículo(s) selecionado(s) — filtro multi-seleção
    precoExtraordinaria: Number    // preço padrão sugerido no prompt
  }

  connect() {
    // Carrega estado inicial renderizado pelo servidor
    const el = document.getElementById("validacao-estado-inicial")
    if (el) {
      const estado = JSON.parse(el.textContent)
      this.atualizarResumo(estado)
    }
  }

  // ── Toggle individual ──────────────────────────────────────
  async classificar(event) {
    const btn      = event.currentTarget
    const tracking = btn.dataset.tracking
    const tipo     = btn.dataset.tipo

    // Pilar extraordinária: ao ATIVAR (botão ainda sem ring-2), pergunta o valor.
    const ativando = !btn.classList.contains("ring-2")
    let valor = null
    if (tipo === "extraordinaria" && ativando) {
      valor = this.pedirValor()
      if (valor === null) return   // admin cancelou
    }

    btn.disabled = true
    try {
      const resp = await this.post(this.urlValue, {
        tracking_id: tracking,
        tipo:        tipo,
        motorista:   this.motoristaValue,
        vehicle:     this.veiculosValue,
        valor:       valor
      })
      // resp.ativo indica se o pilar ficou ligado ou desligado (toggle)
      this.setToggle(tracking, tipo, resp.ativo)
      this.atualizarResumo(resp)
    } catch (e) {
      alert("Erro ao classificar entrega. Tente novamente.")
    } finally {
      btn.disabled = false
    }
  }

  // ── Oculta/mostra o resumo lateral (lista ocupa a largura toda) ──
  toggleResumo() {
    const escondido = this.resumoTarget.classList.toggle("hidden")
    if (this.hasListaColTarget) {
      this.listaColTarget.classList.toggle("lg:col-span-4", escondido)
      this.listaColTarget.classList.toggle("lg:col-span-3", !escondido)
    }
    if (this.hasBtnResumoLabelTarget)
      this.btnResumoLabelTarget.textContent = escondido ? "Mostrar resumo" : "Ocultar resumo"
  }

  // ── Busca na listagem de notas (filtra os cards por NF/local/endereço/veículo) ──
  filtrarBusca(event) {
    const q = (event.currentTarget.value || "").trim().toLowerCase()
    let visiveis = 0
    this.linhaTargets.forEach(l => {
      const ok = q === "" || (l.dataset.busca || "").includes(q)
      l.classList.toggle("hidden", !ok)
      if (ok) visiveis++
    })
    if (this.hasBuscaVaziaTarget)
      this.buscaVaziaTarget.classList.toggle("hidden", q === "" || visiveis > 0)
  }

  // ── Selecionar / desmarcar todos os checkboxes (só os visíveis na busca) ──
  selecionarTodos(event) {
    const marcar = event.currentTarget.checked
    this.checkboxTargets.forEach(c => {
      const linha = c.closest("[data-busca]")
      if (linha && linha.classList.contains("hidden")) return
      c.checked = marcar
    })
    this.atualizarSelecao()
  }

  // ── Estado da seleção ──
  // Os pilares ficam SEMPRE na tela; sem seleção apenas esmaecem. Esconder e
  // remostrar mexia na altura do cabeçalho a cada clique e escondia a ação
  // principal justamente de quem ainda não sabe que precisa selecionar antes.
  atualizarSelecao() {
    const n = this.checkboxTargets.filter(c => c.checked).length

    if (this.hasContadorSelecaoTarget) this.contadorSelecaoTarget.textContent = n
    if (this.hasChipSelecaoTarget)     this.chipSelecaoTarget.classList.toggle("hidden", n === 0)
    if (this.hasBtnLimparTarget)       this.btnLimparTarget.classList.toggle("hidden", n === 0)

    if (this.hasGrupoPilaresTarget) {
      this.grupoPilaresTarget.classList.toggle("opacity-40", n === 0)
      this.grupoPilaresTarget.title = n === 0
        ? "Marque ao menos uma entrega para aplicar em massa"
        : `Aplicar em ${n} entrega(s) — clique de novo no pilar para remover`
    }
  }

  limparSelecao() {
    this.checkboxTargets.forEach(c => (c.checked = false))
    if (this.hasSelecionarTodosTarget) this.selecionarTodosTarget.checked = false
    this.atualizarSelecao()
  }

  // O pilar está ativo (ring-2) na entrega indicada?
  pilarAtivo(tracking, tipo) {
    const grupo = this.togglesTargets.find(t => t.dataset.tracking === tracking)
    if (!grupo) return false
    const btn = grupo.querySelector(`.toggle-btn[data-tipo="${tipo}"]`)
    return !!btn && btn.classList.contains("ring-2")
  }

  // ── Aplicar/remover o pilar nos selecionados (toggle em massa) ──
  async marcarSelecionados(event) {
    const tipo = event.currentTarget.dataset.tipo
    const ids  = this.checkboxTargets.filter(c => c.checked).map(c => c.value)

    if (ids.length === 0) {
      alert("Selecione ao menos uma entrega (checkbox à esquerda).")
      return
    }

    // Toggle em massa: se TODAS as selecionadas já têm o pilar, remove de todas;
    // caso contrário, aplica em todas.
    const remover = ids.every(id => this.pilarAtivo(id, tipo))

    let valor = null
    if (tipo === "extraordinaria" && !remover) {
      valor = this.pedirValor()
      if (valor === null) return
    }

    const resp = await this.post(this.massaUrlValue, {
      tipo:         tipo,
      motorista:    this.motoristaValue,
      vehicle:      this.veiculosValue,
      tracking_ids: ids,
      acao:         remover ? "remover" : "adicionar",
      valor:        valor
    })
    ids.forEach(id => this.setToggle(id, tipo, !remover))
    this.limparSelecao()   // some a barra de ações junto com a seleção
    this.atualizarResumo(resp)
  }

  // ── Helpers ────────────────────────────────────────────────

  async post(url, body) {
    const resp = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Accept":       "application/json",
        "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
      },
      body: JSON.stringify(body)
    })
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
    return resp.json()
  }

  // Liga/desliga UM pilar (os demais pilares da entrega ficam como estão)
  setToggle(tracking, tipo, ativo) {
    const grupo = this.togglesTargets.find(t => t.dataset.tracking === tracking)
    if (!grupo) return

    const btn = grupo.querySelector(`.toggle-btn[data-tipo="${tipo}"]`)
    if (btn) {
      btn.classList.toggle("ring-2", ativo)
      btn.classList.toggle("ring-green-400", ativo)
      btn.classList.toggle("scale-105", ativo)
      btn.classList.toggle("opacity-50", !ativo)
    }

    // a linha está "classificada" se tiver qualquer pilar ligado
    const algumAtivo = grupo.querySelectorAll(".toggle-btn.ring-2").length > 0
    const linha = this.linhaTargets.find(l => l.dataset.tracking === tracking)
    if (linha) linha.dataset.classificada = algumAtivo ? "1" : "0"
  }

  atualizarResumo(dados) {
    const porTipo = dados.por_tipo || {}
    this.qtdNormalTarget.textContent   = porTipo["entrega_normal"] || 0
    this.qtdRetiradaTarget.textContent = porTipo["retirada"]       || 0
    this.qtdBonusTarget.textContent    = porTipo["bonus"]          || 0
    this.qtdDescontoTarget.textContent = porTipo["desconto"]       || 0
    if (this.hasQtdExtraordinariaTarget)
      this.qtdExtraordinariaTarget.textContent = porTipo["extraordinaria"] || 0
    if (this.hasQtdTermoTarget)
      this.qtdTermoTarget.textContent = porTipo["termo"] || 0
    if (this.hasQtdTermoEspecialTarget)
      this.qtdTermoEspecialTarget.textContent = porTipo["termo_especial"] || 0

    const valor = dados.valor_total || 0
    this.valorTotalTarget.textContent =
      "R$ " + valor.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 })

    // Lançamentos manuais do motorista (apontamentos + termo): feedback visual.
    // Ficam fora do denominador de elegíveis (o gate de finalização não muda).
    const manuais = dados.manuais || 0
    if (this.hasQtdManuaisTarget)      this.qtdManuaisTarget.textContent = manuais
    if (this.hasContadorManuaisTarget) this.contadorManuaisTarget.textContent = manuais
    if (this.hasManuaisInfoTarget)     this.manuaisInfoTarget.classList.toggle("hidden", manuais <= 0)

    // Barra/contador refletem o ESCOPO atual (veículo selecionado, se houver).
    const classificadas = (dados.classificadas_escopo ?? dados.classificadas) || 0
    this.contadorClassificadasTarget.textContent = classificadas

    const total = this.totalValue || parseInt(this.contadorTotalTarget.textContent)
    const pct   = total > 0 ? Math.round((classificadas / total) * 100) : 0
    this.percentualTarget.textContent = `${Math.min(pct, 100)}%`

    // Barra com 2 segmentos, proporcionais ao total geral (elegíveis + manuais):
    // laranja/verde = elegíveis classificadas · azul = lançamentos manuais.
    const denom = total + manuais
    this.barraTarget.style.width = denom > 0 ? `${(classificadas / denom) * 100}%` : "0%"
    if (this.hasBarraManuaisTarget)
      this.barraManuaisTarget.style.width = denom > 0 ? `${(manuais / denom) * 100}%` : "0%"

    // Cor do segmento elegível: verde quando todas as elegíveis estão classificadas.
    this.barraTarget.classList.toggle("bg-green-500", pct >= 100)
    this.barraTarget.classList.toggle("bg-orange-500", pct < 100)

    // Botão "Consolidar este veículo" (só existe quando UM veículo está
    // selecionado e ainda não fechado): habilita quando o escopo chega a 100%.
    if (this.hasConsolidarBtnTarget) {
      const pronto = pct >= 100
      this.consolidarBtnTarget.disabled = !pronto
      this.consolidarBtnTarget.classList.toggle("bg-green-600",        pronto)
      this.consolidarBtnTarget.classList.toggle("hover:bg-green-500",  pronto)
      this.consolidarBtnTarget.classList.toggle("text-white",         pronto)
      this.consolidarBtnTarget.classList.toggle("cursor-pointer",     pronto)
      this.consolidarBtnTarget.classList.toggle("bg-[#2a2a2a]",       !pronto)
      this.consolidarBtnTarget.classList.toggle("text-gray-600",      !pronto)
      this.consolidarBtnTarget.classList.toggle("cursor-not-allowed", !pronto)
      if (this.hasConsolidarHintTarget)
        this.consolidarHintTarget.textContent =
          pronto ? "Pronto para consolidar." : "Classifique 100% deste veículo para consolidar."
    }

    if (dados.veiculos_status) this.atualizarChips(dados.veiculos_status)
  }

  // Atualiza os chips "fechar por veículo" (contador + estado fechado) a partir
  // do status devolvido pelo servidor.
  atualizarChips(status) {
    if (!this.hasChipVeiculoTarget) return
    const porVeiculo = {}
    status.forEach(v => { porVeiculo[v.vehicle] = v })

    const LARANJA       = ["border-orange-500", "text-orange-400", "bg-orange-500/10"]
    const VERDE_FECHADO = ["border-green-500", "text-green-400", "bg-green-500/10"]
    const VERDE_PRONTO  = ["border-green-600/50", "text-green-400"]
    const ARQUIVADO     = ["border-dashed", "border-[#3a3a3a]", "text-gray-500"]
    const NEUTRO        = ["border-[#2a2a2a]", "text-gray-300"]
    const TODAS = [...LARANJA, ...VERDE_FECHADO, ...VERDE_PRONTO, ...ARQUIVADO, ...NEUTRO]

    this.chipVeiculoTargets.forEach(chip => {
      const dados = porVeiculo[chip.dataset.vehicle]
      if (!dados) return
      const feito = chip.querySelector("[data-chip-feito]")
      const total = chip.querySelector("[data-chip-total]")
      const check = chip.querySelector("[data-chip-check]")
      const lock  = chip.querySelector("[data-chip-lock]")
      if (feito) feito.textContent = dados.classificadas
      if (total) total.textContent = dados.eligible
      // O check e o cadeado agora são <svg> fixos no HTML — alterna a visibilidade
      // em vez de trocar textContent (que apagaria o SVG).
      if (check) check.classList.toggle("hidden", !dados.completo)
      if (lock)  lock.classList.toggle("hidden", !dados.fechado)

      // Cor determinística: selecionado(laranja) > consolidado(cadeado+verde) >
      // pronto(verde) > arquivado(cinza) > neutro.
      chip.classList.remove(...TODAS)
      if (this.veiculosValue.includes(chip.dataset.vehicle)) {
        chip.classList.add(...LARANJA)
      } else if (dados.fechado) {
        chip.classList.add(...VERDE_FECHADO)
      } else if (dados.completo) {
        chip.classList.add(...VERDE_PRONTO)
      } else if (dados.arquivado) {
        chip.classList.add(...ARQUIVADO)
      } else {
        chip.classList.add(...NEUTRO)
      }
    })
  }

  labelTipo(tipo) {
    return { entrega_normal: "Normal", retirada: "Retirada",
             bonus: "Bônus", desconto: "Desconto",
             extraordinaria: "Extraordinária" }[tipo] || tipo
  }

  // Pergunta o valor da entrega extraordinária (pré-preenchido com o padrão).
  // Retorna o número (>= 0) ou null se o admin cancelar.
  pedirValor() {
    const padrao = (this.precoExtraordinariaValue || 0).toFixed(2).replace(".", ",")
    const entrada = prompt("Valor desta entrega extraordinária (R$):", padrao)
    if (entrada === null) return null
    const num = parseFloat(entrada.replace(",", "."))
    if (isNaN(num) || num < 0) {
      alert("Valor inválido. Informe um número maior ou igual a zero.")
      return null
    }
    return num
  }
}
