<script setup>
/**
 * Suggest Slots dialog — "find me a time window".
 *
 * Opens for an unscheduled or to-reschedule Dispatch Job. Calls the hub
 * /dispatch/suggest-slots endpoint to get 5 best windows across techs,
 * renders them as tappable cards, and emits `apply` with the picked slot
 * so the parent can write it back to the job.
 */
import { ref, computed, inject, watch } from 'vue'
import { Notify } from 'quasar'

const HUB_URL = window.location.hostname === 'localhost'
  ? 'http://localhost:3300'
  : 'https://msg.gigafibre.ca'

const props = defineProps({
  modelValue: Boolean,
  // Minimal job shape — only what we need to query for slots.
  job: { type: Object, default: () => null },
})
const emit = defineEmits(['update:modelValue', 'apply'])

const TECH_COLORS = inject('TECH_COLORS', {})

const loading = ref(false)
const slots = ref([])
const errorMsg = ref('')

async function fetchSlots () {
  if (!props.job) return
  loading.value = true
  errorMsg.value = ''
  slots.value = []
  try {
    const res = await fetch(`${HUB_URL}/dispatch/suggest-slots`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        duration_h: props.job.duration || 1,
        latitude: props.job.latitude || null,
        longitude: props.job.longitude || null,
        limit: 5,
      }),
    })
    const data = await res.json()
    if (!res.ok) throw new Error(data?.error || 'Erreur serveur')
    slots.value = data.slots || []
    if (!slots.value.length) {
      errorMsg.value = 'Aucune plage trouvée dans les 7 prochains jours. Essayer une durée plus courte ou ajouter de la disponibilité.'
    }
  } catch (e) {
    errorMsg.value = e.message || 'Erreur de connexion'
  } finally {
    loading.value = false
  }
}

watch(() => props.modelValue, (open) => {
  if (open) fetchSlots()
})

// ── Date helpers ────────────────────────────────────────────────────────────
function relativeDate (dateStr) {
  const d = new Date(dateStr + 'T12:00:00')
  const today = new Date(); today.setHours(12, 0, 0, 0)
  const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1)
  const diffDays = Math.round((d - today) / 86400000)
  if (diffDays === 0) return "Aujourd'hui"
  if (diffDays === 1) return 'Demain'
  const dayNames = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
  const monthNames = ['janv', 'févr', 'mars', 'avr', 'mai', 'juin', 'juil', 'août', 'sept', 'oct', 'nov', 'déc']
  return `${dayNames[d.getDay()]} ${d.getDate()} ${monthNames[d.getMonth()]}`
}

function positionIcon (position) {
  return { free_day: '🌤', first: '🌅', last: '🌆', between: '↔' }[position] || '🕐'
}

function techColor (techId) {
  return TECH_COLORS[techId] || '#6366f1'
}

// Group slots by date for a cleaner visual flow.
const slotsByDate = computed(() => {
  const groups = []
  for (const s of slots.value) {
    const last = groups[groups.length - 1]
    if (last && last.date === s.date) last.items.push(s)
    else groups.push({ date: s.date, items: [s] })
  }
  return groups
})

function apply (slot) {
  emit('apply', {
    tech_id: slot.tech_id,
    tech_name: slot.tech_name,
    date: slot.date,
    start_time: slot.start_time,
    end_time: slot.end_time,
  })
  Notify.create({
    type: 'positive',
    message: `Assigné à ${slot.tech_name} — ${relativeDate(slot.date)} ${slot.start_time}`,
    timeout: 3000,
  })
  emit('update:modelValue', false)
}

function close () {
  emit('update:modelValue', false)
}
</script>

<template>
<q-dialog :model-value="modelValue" @update:model-value="close">
  <q-card class="suggest-modal">
    <!-- Header -->
    <q-card-section class="suggest-hdr">
      <div class="row items-center">
        <div class="col">
          <div class="text-subtitle1 text-weight-bold">
            <q-icon name="bolt" color="yellow-6" class="q-mr-xs" />
            Trouver une plage horaire
          </div>
          <div v-if="job" class="suggest-job-summary">
            {{ job.subject || 'Travail' }}
            <span class="sep">•</span>
            {{ job.duration || 1 }}h
            <span v-if="job.address" class="sep">•</span>
            <span v-if="job.address" class="job-addr">{{ job.address }}</span>
          </div>
        </div>
        <q-btn flat round dense icon="close" color="grey-5" @click="close" />
      </div>
    </q-card-section>

    <!-- Loading state -->
    <q-card-section v-if="loading" class="suggest-state">
      <q-spinner size="32px" color="indigo-4" />
      <div class="q-mt-sm text-grey-5">Recherche des meilleures plages…</div>
    </q-card-section>

    <!-- Error / empty state -->
    <q-card-section v-else-if="errorMsg" class="suggest-state">
      <q-icon name="sentiment_dissatisfied" size="36px" color="grey-6" />
      <div class="q-mt-sm text-grey-4">{{ errorMsg }}</div>
      <q-btn flat dense color="indigo-4" icon="refresh" label="Réessayer" class="q-mt-sm"
             @click="fetchSlots" />
    </q-card-section>

    <!-- Slot list -->
    <q-card-section v-else class="suggest-list">
      <div v-for="grp in slotsByDate" :key="grp.date" class="slot-group">
        <div class="slot-group-date">{{ relativeDate(grp.date) }}</div>
        <button v-for="s in grp.items" :key="`${s.tech_id}_${s.date}_${s.start_time}`"
                class="slot-card" @click="apply(s)">
          <span class="tech-dot" :style="{ background: techColor(s.tech_id) }"></span>
          <div class="slot-body">
            <div class="slot-line1">
              <span class="tech-name">{{ s.tech_name }}</span>
              <span class="slot-time">{{ s.start_time }} → {{ s.end_time }}</span>
            </div>
            <div class="slot-line2">
              <span class="slot-reason">
                {{ positionIcon(s.position) }} {{ s.reasons[0] }}
              </span>
              <span v-if="s.distance_km != null" class="slot-travel">
                🚗 {{ s.travel_min }} min ({{ s.distance_km }} km)
              </span>
              <span v-else class="slot-travel">🚗 {{ s.travel_min }} min trajet</span>
            </div>
          </div>
          <q-icon name="chevron_right" size="18px" color="indigo-3" />
        </button>
      </div>
      <div class="suggest-tip">
        <q-icon name="info" size="xs" class="q-mr-xs" />
        Cliquer une plage pour assigner immédiatement. Le travail peut ensuite être ajusté par glisser-déposer sur le timeline.
      </div>
    </q-card-section>
  </q-card>
</q-dialog>
</template>

<style scoped>
.suggest-modal {
  width: 520px;
  max-width: 95vw;
  background: #1a1e2e;
  color: #e2e4ef;
}
.suggest-hdr {
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  padding-bottom: 10px;
}
.suggest-job-summary {
  font-size: 12px;
  color: #9ca3af;
  margin-top: 4px;
  line-height: 1.4;
}
.suggest-job-summary .sep { margin: 0 6px; color: #4b5563; }
.suggest-job-summary .job-addr {
  color: #c7d2fe;
  max-width: 300px;
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.suggest-state {
  text-align: center;
  padding: 40px 20px;
}
.suggest-list {
  max-height: 60vh;
  overflow-y: auto;
}
.slot-group { margin-bottom: 14px; }
.slot-group-date {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #6b7280;
  font-weight: 600;
  margin-bottom: 6px;
  padding-left: 2px;
}
.slot-card {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 6px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s;
  color: inherit;
  text-align: left;
  font: inherit;
}
.slot-card:hover {
  background: rgba(99, 102, 241, 0.12);
  border-color: rgba(99, 102, 241, 0.35);
  transform: translateY(-1px);
}
.tech-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.04);
}
.slot-body {
  flex: 1;
  min-width: 0;
}
.slot-line1 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}
.tech-name {
  font-weight: 600;
  font-size: 13.5px;
  color: #e0e7ff;
}
.slot-time {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  color: #fcd34d;
  font-weight: 600;
}
.slot-line2 {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  color: #9ca3af;
}
.slot-reason { color: #c7d2fe; }
.slot-travel { color: #9ca3af; }
.suggest-tip {
  margin-top: 12px;
  padding: 8px 10px;
  background: rgba(99, 102, 241, 0.06);
  border-radius: 6px;
  font-size: 11px;
  color: #9ca3af;
  line-height: 1.4;
  display: flex;
  align-items: flex-start;
}
</style>
