<!--
  JobMediaModule — photos prises par le TECH sur place (app terrain /field/photo, géo-vérifiées vs l'adresse du job)
  + journal d'activité terrain (completion_notes : arrivées géofence, scans d'appareil, notes). Module RÉUTILISABLE
  (détail ticket « Intervention sur site » + volet job Planification). Autonome : charge via roster.jobMedia(name),
  se rafraîchit seul pendant que le panneau est ouvert (les photos arrivent PENDANT la visite).
-->
<template>
  <div v-if="props.name">
    <div class="text-subtitle2 q-mt-md q-mb-xs row items-center">
      Photos &amp; activité terrain
      <span v-if="photos.length" class="text-grey-5 q-ml-sm" style="font-size:10px">· {{ photos.length }} photo(s)</span>
      <q-space />
      <q-btn flat dense round size="sm" icon="refresh" :loading="loading" @click="reload(false)"><q-tooltip>Rafraîchir</q-tooltip></q-btn>
    </div>

    <!-- Photos : vignettes cliquables ; badge « sur place » (distance GPS ↔ adresse du job) = preuve d'adresse ;
         la légende (note du tech) sert à identifier l'appareil photographié. -->
    <div v-if="photos.length" class="jm-grid">
      <div v-for="p in photos" :key="p.file" class="jm-cell" @click="openPhoto(p)">
        <img :src="p.url" loading="lazy" :alt="p.note || 'photo terrain'" />
        <div class="jm-meta">
          <span v-if="p.onsite" class="jm-badge jm-ok">✓ sur place</span>
          <span v-else-if="p.offsite" class="jm-badge jm-warn">⚠ hors adresse</span>
          <span v-if="p.at" class="jm-ts">{{ fmtDT(p.at) }}</span>
        </div>
        <div v-if="p.note" class="jm-note">{{ p.note }}</div>
      </div>
    </div>

    <!-- Journal terrain (plus récent en haut) : arrivé/reparti, scans SN/MAC, photos, hors-zone… -->
    <div v-if="journal.length" class="q-mt-xs">
      <a class="jm-toggle" @click.prevent="showJournal = !showJournal">
        {{ showJournal ? 'Masquer' : 'Voir' }} le journal terrain ({{ journal.length }})
      </a>
      <div v-if="showJournal" class="jm-journal">
        <div v-for="(l, i) in journal" :key="i" class="jm-line">{{ l }}</div>
      </div>
    </div>

    <div v-if="!loading && !photos.length && !journal.length" class="text-grey-5" style="font-size:11px">
      Aucune photo ni activité terrain pour l'instant.
    </div>

    <!-- Plein écran -->
    <q-dialog v-model="viewer">
      <q-card style="max-width:94vw">
        <q-card-section class="q-pa-xs row items-center">
          <div class="text-caption q-ml-sm">
            <b v-if="current && current.onsite" class="text-positive">✓ sur place</b>
            <b v-else-if="current && current.offsite" class="text-warning">⚠ hors adresse</b>
            <span v-if="current && current.geo" class="text-grey-7 q-ml-xs">{{ current.geo }}</span>
            <span v-if="current && current.at" class="text-grey-6 q-ml-xs">· {{ fmtDT(current.at) }}</span>
            <span v-if="current && current.note" class="q-ml-xs">— {{ current.note }}</span>
          </div>
          <q-space /><q-btn flat round dense icon="close" v-close-popup />
        </q-card-section>
        <img v-if="current" :src="current.url" style="max-width:94vw;max-height:82vh;display:block" :alt="current.note || 'photo terrain'" />
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
import * as roster from 'src/api/roster'
import { formatDateTime as fmtDT } from 'src/composables/useFormatters'

const props = defineProps({
  name: { type: String, default: '' }, // docname du Dispatch Job
})

const loading = ref(false)
const photos = ref([])
const journal = ref([])
const showJournal = ref(false)
const viewer = ref(false)
const current = ref(null)

function openPhoto (p) { current.value = p; viewer.value = true }

async function reload (silent = true) {
  if (!props.name) return
  if (!silent) loading.value = true
  try {
    const r = await roster.jobMedia(props.name)
    photos.value = (r && r.photos) || []
    // Journal = lignes non-vides de completion_notes, PLUS RÉCENT EN HAUT (comme le fil du billet).
    journal.value = String((r && r.notes) || '').split('\n').map(s => s.replace(/^•\s*/, '').trim()).filter(Boolean).reverse().slice(0, 60)
  } catch (e) { /* best-effort : le module ne casse jamais le panneau */ } finally { loading.value = false }
}

let pollTimer = null
onMounted(() => {
  reload(false)
  // Les photos/checkpoints arrivent pendant la visite → petit poll tant que le panneau est ouvert (silencieux).
  pollTimer = setInterval(() => { if (document.visibilityState === 'visible') reload(true) }, 60000)
})
onBeforeUnmount(() => { if (pollTimer) clearInterval(pollTimer) })
watch(() => props.name, () => { photos.value = []; journal.value = []; reload(false) })
defineExpose({ reload })
</script>

<style scoped>
.jm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.jm-cell { cursor: pointer; border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden; background: #fafafa; }
.jm-cell img { width: 100%; height: 84px; object-fit: cover; display: block; }
.jm-meta { display: flex; align-items: center; gap: 4px; padding: 2px 5px 0; flex-wrap: wrap; }
.jm-badge { font-size: 9px; font-weight: 700; border-radius: 4px; padding: 0 4px; }
.jm-ok { color: #1b5e20; background: #e6f4ec; }
.jm-warn { color: #8a5a00; background: #fbf0dc; }
.jm-ts { font-size: 9px; color: #90a4ae; }
.jm-note { font-size: 10px; color: #455a64; padding: 0 5px 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jm-toggle { font-size: 11px; color: #5e7a76; cursor: pointer; text-decoration: underline dotted; }
.jm-journal { margin-top: 4px; max-height: 180px; overflow-y: auto; background: #f6f8fb; border-radius: 6px; padding: 6px 8px; }
.jm-line { font-size: 11px; color: #37474f; white-space: pre-wrap; border-top: 1px dashed #e0e6ef; padding: 2px 0; }
.jm-line:first-child { border-top: none; }
</style>
