<!--
  JobTeamField — équipe d'un Dispatch Job (assigné + assistants/renfort + suiveurs) via le champ partagé AssignmentField.
  Module RÉUTILISABLE extrait du volet jobDetail. Il ENCAPSULE la gestion des assistants (roster.addAssistant /
  removeAssistant / getJobTeam) et émet `updated` après chaque changement (le parent rafraîchit l'occupation).
  L'assignation du LEAD reste au parent (émise via `assign-lead` / `unassign-lead`) : le board utilise sa pipeline
  assignNames (groupes / géorepérage), le détail ticket un chemin simple. Slot #right passé à AssignmentField (ex. statut).
-->
<template>
  <AssignmentField
    doctype="Dispatch Job" :doc-name="name"
    :assignee="assignee" :assistants="assistants"
    :tech-options="techOptions" :can-onsite="canOnsite" :assist-loading="teamLoading || busy"
    @assign="v => $emit('assign-lead', v)" @unassign="$emit('unassign-lead')"
    @set-assistant="onSetAssistant" @remove-assistant="onRemoveAssistant">
    <template #right><slot name="right" /></template>
  </AssignmentField>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { Notify } from 'quasar'
import * as roster from 'src/api/roster'
import AssignmentField from 'src/components/shared/AssignmentField.vue'

const props = defineProps({
  name: { type: String, default: '' }, // docname du Dispatch Job
  techId: { type: String, default: '' }, // lead assigné (id)
  techName: { type: String, default: '' }, // lead assigné (nom)
  team: { type: Array, default: null }, // assistants [{ tech_id, tech_name, pinned }] — si null, le module charge lui-même
  techOptions: { type: Array, default: () => [] }, // suggestions (techs + compétences)
  canOnsite: { type: Boolean, default: true }, // niveau « Sur place » (bloc horaire) dispo ?
  teamLoading: { type: Boolean, default: false },
})
const emit = defineEmits(['assign-lead', 'unassign-lead', 'updated'])

const localTeam = ref(props.team || [])
const busy = ref(false)
watch(() => props.team, v => { if (v) localTeam.value = v })

const assignee = computed(() => (props.techName || props.techId) ? { id: props.techId, name: props.techName } : null)
// Nom d'assistant robuste : une vieille ligne peut porter tech_name = « undefined »/« null » → repli sur l'id.
function assistantName (a) { const bad = v => !v || v === 'undefined' || v === 'null'; if (a && !bad(a.tech_name)) return a.tech_name; return (a && !bad(a.tech_id)) ? a.tech_id : '—' }
// onsite = pinned (bloc horaire réservé). Assistant simple (pinned 0) = sur l'équipe sans bloc.
const assistants = computed(() => (localTeam.value || []).map(a => ({ id: a.tech_id, name: assistantName(a), onsite: !!a.pinned })))

async function reloadTeam () {
  if (!props.name) return
  try { const r = await roster.getJobTeam(props.name); localTeam.value = r.assistants || [] } catch (e) { /* garde l'existant */ }
}

// Ajouter / mettre à jour un assistant : { value=id, label, onsite }. Le hub `add` remplace la ligne du même tech_id
// → sert aussi à CHANGER le niveau (assistant ↔ sur place). Nom robuste depuis le libellé de l'option.
async function onSetAssistant ({ value, label, onsite } = {}) {
  const id = value; if (!id || !props.name) return
  const name = (label && String(label).split(' · ')[0].trim()) || String(id)
  busy.value = true
  try {
    await roster.addAssistant(props.name, { tech_id: String(id), tech_name: name, duration_h: 0, pinned: onsite ? 1 : 0 })
    await reloadTeam()
    emit('updated', localTeam.value)
    Notify.create({ type: 'positive', icon: onsite ? 'construction' : 'group_add', message: name + (onsite ? ' — sur place (bloc réservé)' : ' — assistant'), timeout: 2400 })
  } catch (e) { Notify.create({ type: 'negative', message: 'Erreur équipe : ' + (e && e.message), timeout: 3000 }) } finally { busy.value = false }
}
async function onRemoveAssistant (techId) {
  if (!props.name) return
  busy.value = true
  try {
    await roster.removeAssistant(props.name, techId); await reloadTeam(); emit('updated', localTeam.value)
    Notify.create({ type: 'info', message: 'Assistant retiré', timeout: 1600 })
  } catch (e) { Notify.create({ type: 'negative', message: 'Erreur : ' + (e && e.message), timeout: 3000 }) } finally { busy.value = false }
}

onMounted(() => { if (props.team == null && props.name) reloadTeam() })
</script>
