<!--
  GeofenceTimeline — suivi terrain (géofencing GPS) façon suivi de colis : Assigné → En route → Arrivé → Reparti.
  Module RÉUTILISABLE extrait du volet jobDetail (PlanificationPage). Autonome : il charge lui-même la timeline
  via roster.jobGeofence(name) si aucun objet `geofence` n'est fourni. Aucune dépendance à l'état de la page.
  N'affiche rien si le job n'a pas d'état de géofence (pas de bruit).
-->
<template>
  <div v-if="gf && gf.state" class="jd-geo">
    <div class="text-subtitle2 row items-center q-mb-xs"><q-icon name="my_location" size="18px" class="q-mr-xs" color="teal-7" /> Suivi terrain (GPS)</div>
    <div class="jd-geo-track">
      <div v-for="s in timeline" :key="s.k" class="jd-geo-step" :class="{ done: s.done, current: s.current }">
        <div class="jd-geo-ic"><q-icon :name="s.icon" size="15px" /></div>
        <div class="jd-geo-lbl">{{ s.label }}<span v-if="s.at" class="jd-geo-at">{{ s.at }}</span></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import * as roster from 'src/api/roster'

const props = defineProps({
  name: { type: String, default: '' }, // docname du Dispatch Job
  geofence: { type: Object, default: null }, // objet déjà chargé { state, events } — sinon on le fetch
})

const GEO_STEPS = [
  { k: 'assigned', label: 'Assigné', icon: 'assignment_ind' },
  { k: 'en_route', label: 'En route', icon: 'directions_car' },
  { k: 'on_site', label: 'Arrivé sur place', icon: 'location_on' },
  { k: 'departed', label: 'Reparti', icon: 'check_circle' },
]

const loaded = ref(null)
const gf = computed(() => props.geofence || loaded.value)

const timeline = computed(() => {
  const g = gf.value; const events = (g && g.events) || []
  const atOf = (k) => { const e = [...events].reverse().find(x => x.status === k); return e ? new Date(e.at).toLocaleTimeString('fr-CA', { hour: '2-digit', minute: '2-digit', timeZone: 'America/Toronto' }) : null }
  const order = { assigned: 0, en_route: 1, on_site: 2, departed: 3 }
  const curIdx = order[(g && g.state) || 'assigned'] ?? 0
  return GEO_STEPS.map((s, i) => ({ ...s, at: s.k === 'assigned' ? null : atOf(s.k), done: i <= curIdx, current: i === curIdx }))
})

async function load () {
  if (props.geofence || !props.name) return
  try { loaded.value = await roster.jobGeofence(props.name) } catch (e) { loaded.value = null }
}
watch(() => props.name, () => { loaded.value = null; load() })
onMounted(load)
</script>

<style scoped>
.jd-geo { margin-top: 12px; padding: 10px 8px; border: 1px solid #d6eeeb; background: #f3fbfa; border-radius: 8px; }
.jd-geo-track { display: flex; align-items: flex-start; }
.jd-geo-step { flex: 1; text-align: center; position: relative; }
.jd-geo-step::before { content: ''; position: absolute; top: 13px; left: -50%; width: 100%; height: 2px; background: #cfe3e0; z-index: 0; }
.jd-geo-step:first-child::before { display: none; }
.jd-geo-step.done::before { background: #26a69a; }
.jd-geo-ic { position: relative; z-index: 1; width: 28px; height: 28px; margin: 0 auto; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: #e0e0e0; color: #fff; }
.jd-geo-step.done .jd-geo-ic { background: #26a69a; }
.jd-geo-step.current .jd-geo-ic { box-shadow: 0 0 0 3px rgba(38,166,154,.3); }
.jd-geo-lbl { font-size: 10.5px; color: #607d8b; margin-top: 3px; line-height: 1.25; }
.jd-geo-step.done .jd-geo-lbl { color: #37474f; font-weight: 600; }
.jd-geo-at { display: block; font-size: 10px; color: #26a69a; font-weight: 700; }
</style>
