// app/javascript/controllers/carrossel_controller.js
// Stimulus — paginação em "carrossel" para listas longas: mostra uma página de
// itens por vez, com setas grandes e o indicador "1–5 de 12".
//
// TAMANHO DE PÁGINA POR TELA (é o ponto do controller):
//   • celular (até 640px)      → 5 itens  — cada card ocupa muita altura;
//                                 10 já viravam rolagem infinita;
//   • até 1366px               → 10 itens — tablet e notebook pequeno;
//   • acima disso              → lista INTEIRA, sem setas. Em monitor grande a
//                                 lista cabe e esconder item só atrapalha (o
//                                 Ctrl+F do navegador não acha o que está oculto).
//
// O corte é reavaliado no resize/rotação: girar o celular ou encostar a janela
// na lateral já muda o comportamento, e o item que estava no topo continua na
// tela (a posição é guardada pelo ÍNDICE do item, não pelo número da página).
//
// Os itens já vêm todos no HTML; aqui só escondemos os de fora da página. Por
// isso não serve para listas de centenas de itens (aí é paginação no servidor).
//
// Uso:
//   <div data-controller="carrossel"
//        data-carrossel-tamanho-value="10"           <- itens por página
//        data-carrossel-tamanho-compacto-value="5"   <- itens no celular
//        data-carrossel-largura-compacta-value="640" <- até aqui é "celular"
//        data-carrossel-max-largura-value="1366">    <- acima disso, mostra tudo
//     <div data-carrossel-target="item">…</div>
//     <%= render 'shared/carrossel_controles' %>
//   </div>
//
// Um item com data-carrossel-inicial="true" (ex.: o motorista com a composição
// aberta) define em qual página o carrossel abre — senão o clique dele "sumia".

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["item", "controles", "indicador", "anterior", "proximo"]
  static values  = {
    tamanho:         { type: Number, default: 10 },
    tamanhoCompacto: { type: Number, default: 5 },
    larguraCompacta: { type: Number, default: 640 },
    maxLargura:      { type: Number, default: 1366 }
  }

  connect() {
    // Âncora = índice do primeiro item da página atual. Guardar o ÍNDICE (e não
    // o número da página) é o que mantém o mesmo item na tela quando o tamanho
    // da página muda junto com a largura.
    this.ancora = this.indiceInicial()
    this._aoRedimensionar = () => this.render()
    window.addEventListener("resize", this._aoRedimensionar)
    this.render()
  }

  disconnect() {
    window.removeEventListener("resize", this._aoRedimensionar)
  }

  proxima()  { this.ir(this.pagina + 1) }
  anterior() { this.ir(this.pagina - 1) }

  ir(destino) {
    const pagina = Math.min(Math.max(destino, 0), this.totalPaginas - 1)
    this.ancora = pagina * this.tamanho
    this.render()
    // Volta ao topo da lista: sem isso, na página seguinte o leitor continua
    // vendo o fim da anterior e parece que nada mudou.
    this.element.scrollIntoView({ behavior: "smooth", block: "start" })
  }

  get tamanho() {
    return window.innerWidth <= this.larguraCompactaValue
      ? this.tamanhoCompactoValue
      : this.tamanhoValue
  }

  // Tela grande: sem paginação (a lista inteira aparece).
  get paginando() {
    return window.innerWidth <= this.maxLarguraValue &&
           this.itemTargets.length > this.tamanho
  }

  get totalPaginas() {
    return Math.max(Math.ceil(this.itemTargets.length / this.tamanho), 1)
  }

  get pagina() {
    return Math.min(Math.floor(this.ancora / this.tamanho), this.totalPaginas - 1)
  }

  indiceInicial() {
    const i = this.itemTargets.findIndex((el) => el.dataset.carrosselInicial === "true")
    return i < 0 ? 0 : i
  }

  render() {
    const total = this.itemTargets.length

    if (!this.paginando) {
      this.itemTargets.forEach((item) => item.classList.remove("hidden"))
      this.controlesTargets.forEach((el) => el.classList.add("hidden"))
      return
    }

    const inicio = this.pagina * this.tamanho
    const fim    = inicio + this.tamanho

    this.itemTargets.forEach((item, i) => {
      item.classList.toggle("hidden", i < inicio || i >= fim)
    })

    if (!this.hasControlesTarget) return
    this.controlesTargets.forEach((el) => el.classList.remove("hidden"))

    // "1–5 de 12" e não "página 1 de 3": quem lê quer saber quantos itens
    // existem, não quantas páginas a tela tem.
    const rotulo = `${inicio + 1}–${Math.min(fim, total)} de ${total}`
    this.indicadorTargets.forEach((el) => { el.textContent = rotulo })

    // Plural: o mesmo controle aparece em dois layouts (setas laterais em tela
    // com espaço, barra flutuante no rodapé no celular) e os dois precisam
    // desabilitar juntos.
    this.anteriorTargets.forEach((b) => this.alternar(b, this.pagina === 0))
    this.proximoTargets.forEach((b) => this.alternar(b, this.pagina >= this.totalPaginas - 1))
  }

  // Botão de ponta: desabilitado de verdade (não só apagado), para o toque não
  // "funcionar sem fazer nada".
  alternar(botao, desligado) {
    botao.disabled = desligado
    botao.classList.toggle("opacity-30", desligado)
    botao.classList.toggle("pointer-events-none", desligado)
  }
}
