<script setup>
/**
 * SuggestSlotsDialog — « Trouver un créneau » : pour un NOUVEAU job à une adresse,
 * interroge le hub (POST /dispatch/suggest-slots : gap-finding par tech + tampon de
 * route + classement proximité) et propose les meilleurs créneaux. Le choix émet
 * 'select' avec le créneau + l'adresse/coords/durée → l'appelant pré-remplit la
 * création de job (tech + date + heure + adresse). Backend déjà en place.
 */
import { reactive, ref } from 'vue'
import { Notify } from 'quasar'
import { suggestSlots } from 'src/api/dispatch'
import { useAddressSearch } from 'src/composables/useAddressSearch'

defineProps({ modelValue: { type: Boolean, default: false } })
const emit = defineEmits(['update:modelValue', 'select'])

const { addrResults, addrLoading, searchAddr, selectAddr } = useAddressSearch()
const target = reactive({ address: '', latitude: null, longitude: null, ville: '' })
const durationH = ref(1)
const afterDate = ref(new Date().toLocaleDateString('en-CA', { timeZone: 'America/Toronto' }))
const loading = ref(false)
const slots = ref([])
const searched = ref(false)

function onPickAddr (addr) { selectAddr(addr, target) }

async function search () {
  if (target.latitude == null || target.longitude == null) {
    Notify.create({ type: 'warning', message: 'Choisis une adresse (pour situer les créneaux les plus proches).', timeout: 3000 })
    return
  }
  loading.value = true; searched.value = true
  try {
    slots.value = await suggestSlots({
      duration_h: durationH.value, latitude: target.latitude, longitude: target.longitude,
      after_date: afterDate.value, limit: 8,
    })
  } catch (e) {
    Notify.create({ type: 'negative', message: 'Recherche de créneaux impossible : ' + (e.message || e), timeout: 4000 })
    slots.value = []
  } finally { loading.value = false }
}

function pick (s) {
  emit('select', { ...s, _address: target.address, _latitude: target.latitude, _longitude: target.longitude, _duration: durationH.value })
  emit('update:modelValue', false)
}

const DOW = ['dim', 'lun', 'mar', 'mer', 'jeu', 'ven', 'sam']
function dayLabel (iso) { const d = new Date(iso + 'T12:00:00'); return DOW[d.getDay()] + ' ' + iso.slice(8) + '/' + iso.slice(5, 7) }
</script>

<template>
  <q-dialog :model-value="modelValue" @update:model-value="v => emit('update:modelValue', v)">
    <q-card style="width:520px;max-width:95vw">
      <q-card-section class="row items-center q-pb-none">
        <q-icon name="event_available" color="primary" size="24px" class="q-mr-sm" />
        <div class="text-h6">Trouver un créneau</div>
        <q-space /><q-btn flat round dense icon="close" @click="emit('update:modelValue', false)" />
      </q-card-section>

      <q-card-section class="q-gutter-sm">
        <div class="text-caption text-grey-7">Saisis l'adresse du client + la durée : on classe les meilleurs créneaux (tech le plus proche, trou dans l'horaire, moins de route).</div>
        <q-input dense outlined v-model="target.address" label="Adresse du client" clearable
                 @update:model-value="searchAddr" :loading="addrLoading" autofocus>
          <template #prepend><q-icon name="place" /></template>
          <q-menu v-if="addrResults.length" no-focus fit>
            <q-list dense style="min-width:340px;max-height:40vh;overflow:auto">
              <q-item v-for="(a, i) in addrResults" :key="i" clickable v-close-popup @click="onPickAddr(a)">
                <q-item-section>{{ a.address_full }}</q-item-section>
              </q-item>
            </q-list>
          </q-menu>
        </q-input>
        <div class="row q-col-gutter-sm">
          <q-input class="col" dense outlined type="number" v-model.number="durationH" label="Durée (h)" :min="0.5" :max="8" :step="0.5">
            <template #prepend><q-icon name="schedule" /></template>
          </q-input>
          <q-input class="col" dense outlined type="date" v-model="afterDate" label="À partir du">
            <template #prepend><q-icon name="event" /></template>
          </q-input>
        </div>
        <q-btn unelevated color="primary" icon="search" label="Chercher des créneaux" class="full-width"
               :loading="loading" :disable="target.latitude == null" @click="search" no-caps />
      </q-card-section>

      <q-separator v-if="searched" />
      <q-card-section v-if="searched" style="max-height:46vh;overflow:auto" class="q-pt-sm">
        <div v-if="loading" class="text-center q-pa-md"><q-spinner size="26px" color="primary" /></div>
        <div v-else-if="!slots.length" class="text-grey-6 text-center q-pa-md">Aucun créneau disponible sur l'horizon — élargis la date ou libère un tech.</div>
        <q-list v-else separator>
          <q-item v-for="(s, i) in slots" :key="i" clickable @click="pick(s)" class="rounded-borders">
            <q-item-section avatar>
              <q-avatar size="34px" color="blue-grey-1" text-color="blue-grey-8" class="text-weight-bold" style="font-size:12px">{{ dayLabel(s.date).slice(0, 3) }}</q-avatar>
            </q-item-section>
            <q-item-section>
              <q-item-label class="text-weight-medium">{{ dayLabel(s.date) }} · {{ s.start_time }}–{{ s.end_time }}</q-item-label>
              <q-item-label caption>{{ s.tech_name }}<span v-if="s.travel_min"> · 🚗 {{ s.travel_min }} min<span v-if="s.distance_km"> ({{ s.distance_km }} km)</span></span></q-item-label>
              <q-item-label caption class="text-grey-6">{{ (s.reasons || []).join(' · ') }}</q-item-label>
            </q-item-section>
            <q-item-section side><q-icon name="chevron_right" color="primary" /></q-item-section>
          </q-item>
        </q-list>
      </q-card-section>
    </q-card>
  </q-dialog>
</template>
