<template>
  <section class="display-page">
    <div class="campo">
      <span v-if="state.order">
        <!-- Ordine visualizzazione: home / guest -->
        <div class="hea home">
          <span :style="{ 'float': 'left' }">
            {{ state.sp.nomi.home }}
            <span class="serv-slot">
              <img v-show="servHome" src="/serv.png" width="25" alt="Servizio" />
            </span>
            <span v-if="state.visuForm" class="score-inline">{{ punt.home }}</span>
          </span>
          <span class="mr3" :style="{ 'float': 'right' }">set {{ set.home }}</span>
        </div>

        <div class="hea guest">
          <span :style="{ 'float': 'right' }">
            <span v-if="state.visuForm" class="score-inline">{{ punt.guest }}</span>
            <span class="serv-slot">
              <img v-show="!servHome" src="/serv.png" width="25" alt="Servizio" />
            </span>
            {{ state.sp.nomi.guest }}
          </span>
          <span class="ml3" :style="{ 'float': 'left' }">set {{ set.guest }}</span>
        </div>

        <span v-if="state.visuForm">
          <div class="col form home">
            <div class="formdiv" v-for="x in [3, 2, 1, 4, 5, 0]" :key="'hf'+x">
              {{ state.sp.form.home[x] }}
            </div>
          </div>
          <div class="col form guest">
            <div class="formdiv" v-for="x in [3, 2, 1, 4, 5, 0]" :key="'gf'+x">
              {{ state.sp.form.guest[x] }}
            </div>
          </div>
        </span>
        <span v-else>
          <div class="punteggio-container">
            <div class="col punt home">{{ punt.home }}</div>
            <div class="col punt guest">{{ punt.guest }}</div>
          </div>
        </span>
      </span>

      <span v-else>
        <!-- Ordine visualizzazione: guest / home -->
        <div class="hea guest">
          <span :style="{ 'float': 'left' }">
            {{ state.sp.nomi.guest }}
            <span class="serv-slot">
              <img v-show="!servHome" src="/serv.png" width="25" alt="Servizio" />
            </span>
            <span v-if="state.visuForm" class="score-inline">{{ punt.guest }}</span>
          </span>
          <span class="mr3" :style="{ 'float': 'right' }">set {{ set.guest }}</span>
        </div>

        <div class="hea home">
          <span :style="{ 'float': 'right' }">
            <span v-if="state.visuForm" class="score-inline">{{ punt.home }}</span>
            <span class="serv-slot">
              <img v-show="servHome" src="/serv.png" width="25" alt="Servizio" />
            </span>
            {{ state.sp.nomi.home }}
          </span>
          <span class="ml3" :style="{ 'float': 'left' }">set {{ set.home }}</span>
        </div>

        <span v-if="state.visuForm">
          <div class="col form guest">
            <div class="formdiv" v-for="x in [3, 2, 1, 4, 5, 0]" :key="'gf2'+x">
              {{ state.sp.form.guest[x] }}
            </div>
          </div>
          <div class="col form home">
            <div class="formdiv" v-for="x in [3, 2, 1, 4, 5, 0]" :key="'hf2'+x">
              {{ state.sp.form.home[x] }}
            </div>
          </div>
        </span>
        <span v-else>
          <div class="punteggio-container">
            <div class="col punt guest">{{ punt.guest }}</div>
            <div class="col punt home">{{ punt.home }}</div>
          </div>
        </span>
      </span>

      <div class="striscia" v-if="state.visuStriscia">
        <span class="striscia-nome text-bold">{{ state.sp.nomi.home }}</span>
        <div class="striscia-items" ref="homeItems">
          <div v-for="(h, i) in stricciaStrip.home" :key="'sh'+i"
               class="item" :class="{ 'item-vuoto': h === ' ' }">
            {{ h }}
          </div>
        </div>
        <span class="striscia-nome text-bold guest-striscia">{{ state.sp.nomi.guest }}</span>
        <div class="striscia-items guest-striscia" ref="guestItems">
          <div v-for="(h, i) in stricciaStrip.guest" :key="'sg'+i"
               class="item" :class="{ 'item-vuoto': h === ' ' }">
            {{ h }}
          </div>
        </div>
      </div>

      <!-- Indicatore stato connessione -->
      <div class="connection-status" :class="{ connected: wsConnected, disconnected: !wsConnected }">
        <span class="dot"></span>
        {{ wsConnected ? '' : 'Disconnesso' }}
      </div>
    </div>

    <!-- Overlay time out: proietta il video spot a tutto schermo -->
    <div v-if="state.timeout" class="timeout-overlay">
      <div class="timeout-countdown">{{ timeoutCountdown }}</div>
      <video v-if="state.timeoutVideo && !mostraPlaceholder" ref="spotVideo" class="timeout-video"
        :class="{ 'timeout-video--fading': timeoutFading }" playsinline></video>
      <div v-else class="timeout-placeholder">
        TIME OUT<br />{{ state.sp.nomi[state.timeoutTeam] }}
      </div>
    </div>
  </section>
</template>

<script>
import { createWsMixin } from '../wsMixin.js'

export default {
  name: "DisplayPage",
  mixins: [createWsMixin('display')],
  data() {
    return {
      mostraPlaceholder: false, // video terminato prima dei 30s: mostra l'immagine "TIME OUT"
      spotVideoDuration: null,  // durata reale del video in riproduzione, nota dopo il loadedmetadata
      nowTick: Date.now(),
      timeoutTicker: null,
    }
  },
  mounted() {
    if (this.isMobile()) {
      try { document.documentElement.requestFullscreen() } catch (e) {}
    }
    if (this.state.timeout) this.avviaTimeout()
  },
  beforeUnmount() {
    this.fermaTimeoutTicker()
  },
  computed: {
    timeoutRemaining() {
      if (!this.state.timeout || !this.state.timeoutStartedAt) return 30
      const trascorsi = (this.nowTick - this.state.timeoutStartedAt) / 1000
      return Math.max(0, Math.ceil(30 - trascorsi))
    },
    timeoutCountdown() {
      const r = this.timeoutRemaining
      const m = String(Math.floor(r / 60)).padStart(2, '0')
      const s = String(r % 60).padStart(2, '0')
      return `${m}:${s}`
    },
    timeoutFading() {
      // Video più lungo di 30s: dissolvenza negli ultimi istanti prima dello stop del server.
      if (!this.spotVideoDuration || this.spotVideoDuration <= 30) return false
      return this.timeoutRemaining <= 1
    },
    stricciaStrip() {
      const currentSet = this.state.sp.striscia.at(-1)
      if (!currentSet) return { home: [], guest: [] }
      let h = 0, g = 0
      const home = [], guest = []
      for (const scorer of currentSet.ris) {
        if (scorer === 'h') { h++; home.push(h); guest.push(' ') }
        else               { g++; guest.push(g); home.push(' ') }
      }
      return { home, guest }
    },
  },
  watch: {
    'state.sp.striscia': {
      deep: true,
      handler() {
        this.$nextTick(() => {
          if (this.$refs.homeItems)  this.$refs.homeItems.scrollLeft  = this.$refs.homeItems.scrollWidth
          if (this.$refs.guestItems) this.$refs.guestItems.scrollLeft = this.$refs.guestItems.scrollWidth
        })
      }
    },
    'state.timeout': {
      handler(attivo) {
        attivo ? this.avviaTimeout() : this.fermaTimeout()
      },
    },
  },
  methods: {
    avviaTimeoutTicker() {
      this.fermaTimeoutTicker()
      this.nowTick = Date.now()
      this.timeoutTicker = setInterval(() => { this.nowTick = Date.now() }, 200)
    },
    fermaTimeoutTicker() {
      if (this.timeoutTicker) { clearInterval(this.timeoutTicker); this.timeoutTicker = null }
    },
    async avviaTimeout() {
      this.mostraPlaceholder = !this.state.timeoutVideo
      this.spotVideoDuration = null
      this.avviaTimeoutTicker()
      if (!this.state.timeoutVideo) return
      await this.$nextTick()
      this.caricaSpotCorrente()
    },
    fermaTimeout() {
      this.fermaTimeoutTicker()
      const video = this.$refs.spotVideo
      if (video) { video.pause(); video.removeAttribute('src'); video.load() }
      this.mostraPlaceholder = false
      this.spotVideoDuration = null
    },
    caricaSpotCorrente() {
      const video = this.$refs.spotVideo
      if (!video || !this.state.timeoutVideo) return
      video.src = '/spot/' + encodeURIComponent(this.state.timeoutVideo)
      video.onloadedmetadata = () => {
        this.spotVideoDuration = video.duration
        // Riconnessione a metà time out: riallinea il video al punto corretto.
        const trascorsi = this.state.timeoutStartedAt ? (Date.now() - this.state.timeoutStartedAt) / 1000 : 0
        if (trascorsi > 0.5 && trascorsi < video.duration) video.currentTime = trascorsi
      }
      // Video più corto dei 30s: a fine riproduzione mostra l'immagine "TIME OUT" fino allo stop del server.
      video.onended = () => { this.mostraPlaceholder = true }
      this.playSpot()
    },
    playSpot() {
      const video = this.$refs.spotVideo
      if (!video) return
      // Prova con audio; se il browser blocca l'autoplay con suono, ripiega su muto.
      video.muted = false
      const p = video.play()
      if (p && typeof p.catch === 'function') {
        p.catch(() => { video.muted = true; video.play().catch(() => {}) })
      }
    },
    onWsMessage(msg) {
      if (msg.type === 'speak') this.speakOnDisplay(msg.text)
      else if (msg.type === 'error') console.error('[Display] Server error:', msg.message)
    },
    isMobile() {
      return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
    },
    speakOnDisplay(text) {
      if (typeof text !== 'string' || !text.trim() || !('speechSynthesis' in window)) return
      const utterance = new SpeechSynthesisUtterance(text.trim())
      const voices = window.speechSynthesis.getVoices()
      utterance.voice = voices.find(v => v.name === 'Google italiano')
        || voices.find(v => v.lang?.toLowerCase().startsWith('it'))
        || null
      utterance.lang = 'it-IT'
      window.speechSynthesis.cancel()
      window.speechSynthesis.speak(utterance)
    },
  },
}
</script>

<style scoped>
.display-page {
  width: 100%;
  height: 100vh;
  background: #111;
  font-family: 'Inter', system-ui, sans-serif;
  overflow: hidden;
}

.connection-status {
  position: fixed;
  top: 8px;
  right: 8px;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 5px;
  z-index: 100;
  transition: opacity 0.5s;
}

.connection-status.connected {
  opacity: 0;
}

.connection-status.disconnected {
  background: #c62828;
  color: white;
  opacity: 1;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.connected .dot {
  background: #2e7d32;
}

.disconnected .dot {
  background: #ff6b6b;
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.guest-striscia {
  color: white;
}

.punteggio-container {
  width: 100%;
  display: flex;
}

.punt {
  font-size: 60vh;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 50vh;
  min-width: 50vw;
  max-width: 50vw;
  overflow: hidden;
  box-sizing: border-box;
}

.timeout-overlay {
  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 500;
}

.timeout-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 0.8s ease-out;
}

.timeout-video--fading {
  opacity: 0;
}

.timeout-countdown {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  background: rgba(0, 0, 0, 0.5);
  font-size: 4vh;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.05em;
  padding: 6px 18px;
  border-radius: 12px;
  z-index: 501;
}

.timeout-placeholder {
  color: #ff9800;
  font-size: 14vh;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.3;
  animation: timeout-pulse 1.2s ease-in-out infinite;
}

@keyframes timeout-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
</style>
