<template>
  <q-dialog :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)" persistent>
    <q-card style="width:580px;max-width:90vw">
      <!-- Header -->
      <q-card-section class="row items-center q-pb-sm" style="border-bottom:1px solid var(--ops-border, #e2e8f0)">
        <div class="col">
          <div class="text-subtitle1 text-weight-bold">{{ title }}</div>
          <div v-if="contextLabel" class="text-caption text-grey-6">{{ contextLabel }}</div>
        </div>
        <q-btn flat round dense icon="close" @click="$emit('update:modelValue', false)" />
      </q-card-section>

      <!-- Form -->
      <q-card-section class="q-pt-md q-gutter-sm">
        <q-input v-model="form.subject" label="Sujet" dense outlined autofocus
                 :rules="[v => !!v?.trim() || 'Requis']" />

        <q-select v-model="form.priority" :options="priorityOptions" label="Priorité"
                  dense outlined emit-value map-options />

        <!-- Description / Notes (essentiel — le contenu du ticket/tâche) -->
        <q-input v-model="form.description" :label="mode === 'work-order' ? 'Notes' : 'Description'"
                 type="textarea" dense outlined autogrow style="min-height:60px" />

        <!-- Bascule : n'afficher d'abord que l'essentiel ; révéler le reste à la demande -->
        <q-btn flat dense no-caps size="sm" class="text-grey-7"
               :icon="showAdvanced ? 'expand_less' : 'expand_more'"
               :label="showAdvanced ? 'Moins d\'options' : 'Plus d\'options'"
               @click="showAdvanced = !showAdvanced" />

        <!-- ══ Champs secondaires — révélés à la demande ══ -->
        <div v-show="showAdvanced" class="q-gutter-sm">
          <div class="row q-gutter-sm">
            <q-select v-if="fields.showJobType" v-model="form.job_type" :options="jobTypeOptions"
                      label="Type de travail" dense outlined emit-value map-options class="col" />

            <q-select v-if="fields.showIssueType" v-model="form.issue_type" :options="issueTypeOptions"
                      label="Type" dense outlined emit-value map-options clearable class="col" />
          </div>

        <!-- Service location (ticket mode, when locations available) -->
        <q-select v-if="fields.showServiceLocation && locationOptions.length"
                  v-model="form.service_location" :options="locationOptions"
                  label="Adresse" dense outlined emit-value map-options clearable />

        <!-- Address autocomplete (work-order mode) -->
        <div v-if="fields.showAddress">
          <q-input v-model="form.address" label="Adresse" dense outlined
                   @update:model-value="searchAddr" />
          <q-list v-if="addrResults.length" dense bordered class="q-mt-xs" style="border-radius:6px;max-height:160px;overflow-y:auto">
            <q-item v-for="a in addrResults" :key="a.address_full" clickable @click="onSelectAddr(a)">
              <q-item-section>
                <q-item-label class="text-caption">{{ a.address_full }}</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </div>

        <!-- Duration -->
        <q-input v-if="fields.showDuration" v-model.number="form.duration_h"
                 label="Durée (heures)" type="number" dense outlined min="0.25" step="0.5" />

        <!-- Tags/Skills -->
        <div v-if="fields.showTags">
          <div class="text-caption text-grey-7 q-mb-xs">Tags / Skills</div>
          <TagEditor
            v-model="form.tags"
            :all-tags="allTagsList"
            :get-color="getTagColor"
            :can-create="true"
            :can-edit="true"
            :show-level="mode === 'work-order'"
            :show-required="mode === 'work-order'"
            placeholder="Ajouter un tag…"
            @create="onCreateTag"
            @update-tag="onUpdateTag"
            @rename-tag="onRenameTag"
            @delete-tag="onDeleteTag"
          />
        </div>

        <!-- Parent dependency -->
        <q-select v-model="form.depends_on" label="Dépendance parent (optionnel)"
                  dense outlined clearable use-input hide-selected fill-input
                  :options="parentOpts" emit-value map-options
                  @filter="onParentFilter" input-debounce="0">
          <template v-slot:no-option>
            <q-item>
              <q-item-section class="text-grey text-caption">Aucun résultat</q-item-section>
            </q-item>
          </template>
          <template v-slot:option="{ opt, itemProps }">
            <q-item v-bind="itemProps">
              <q-item-section side style="min-width:48px">
                <q-badge :color="opt.type === 'Issue' ? 'green-3' : 'teal-3'" :label="opt.type === 'Issue' ? 'Ticket' : 'Tâche'" />
              </q-item-section>
              <q-item-section>
                <q-item-label class="text-caption">{{ opt.label }}</q-item-label>
              </q-item-section>
            </q-item>
          </template>
        </q-select>

        <!-- Technician + Optimal (work-order) -->
        <div v-if="fields.showTech && techOptions.length">
          <div class="row items-center q-gutter-sm">
            <q-select v-model="form.assigned_tech" :options="techOptions" label="Technicien"
                      dense outlined clearable emit-value map-options class="col" />
            <q-btn unelevated color="deep-purple-6" icon="bolt" label="Optimal"
                   :loading="findingBest" @click="findBestTech" dense style="height:40px" />
          </div>
          <!-- Best tech ranking -->
          <div v-if="ranking.length" class="best-tech-ranking q-mt-sm">
            <div class="ranking-header row items-center justify-between q-px-sm q-py-xs">
              <span class="text-caption text-weight-bold">Classement optimal</span>
              <q-btn flat dense round size="xs" icon="close" @click="ranking = []" />
            </div>
            <q-list dense separator>
              <q-item v-for="(r, idx) in ranking" :key="r.techId" clickable
                      @click="form.assigned_tech = r.techId; ranking = []"
                      :class="{ 'bg-deep-purple-1': form.assigned_tech === r.techId }">
                <q-item-section avatar style="min-width:32px">
                  <span v-if="idx === 0" style="font-size:18px">&#x1F947;</span>
                  <span v-else-if="idx === 1" style="font-size:18px">&#x1F948;</span>
                  <span v-else-if="idx === 2" style="font-size:18px">&#x1F949;</span>
                  <span v-else class="text-grey-6 text-caption">#{{ idx + 1 }}</span>
                </q-item-section>
                <q-item-section>
                  <q-item-label class="text-weight-medium">{{ r.techName }}</q-item-label>
                  <q-item-label caption>{{ r.reasons.join(' · ') }}</q-item-label>
                </q-item-section>
                <q-item-section side>
                  <q-btn flat dense size="sm" color="deep-purple" label="Choisir"
                         @click.stop="form.assigned_tech = r.techId; ranking = []" />
                </q-item-section>
              </q-item>
            </q-list>
          </div>
        </div>

        <!-- Scheduled date -->
        <q-input v-if="fields.showScheduledDate" v-model="form.scheduled_date"
                 label="Date prévue (optionnel)" type="date" dense outlined />

        </div>
      </q-card-section>

      <!-- Actions -->
      <q-card-actions align="right" class="q-px-md q-pb-md">
        <q-btn flat label="Annuler" color="grey-7" @click="$emit('update:modelValue', false)" />
        <q-btn unelevated :label="submitLabel" color="primary"
               :loading="submitting" :disable="!form.subject?.trim()" @click="onSubmit" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { computed, ref, watch, toRef } from 'vue'
import { Notify } from 'quasar'
import { useUnifiedCreate } from 'src/composables/useUnifiedCreate'
import { useAddressSearch } from 'src/composables/useAddressSearch'
import TagEditor from 'src/components/shared/TagEditor.vue'

const props = defineProps({
  modelValue:   { type: Boolean, default: false },
  mode:         { type: String, default: 'ticket' },    // 'ticket' | 'task' | 'work-order'
  context:      { type: Object, default: () => ({}) },  // pre-fill: customer, subject, service_location, etc.
  technicians:  { type: Array, default: () => [] },
  locations:    { type: Array, default: () => [] },      // for ticket mode: customer's service locations
  existingJobs: { type: Array, default: () => [] },
  // Tag overrides (if provided, uses these instead of internal fetch)
  externalTags:    { type: Array, default: null },
  externalGetColor:{ type: Function, default: null },
  // Custom submit handler — if provided, replaces default submit logic
  // Receives form data object, should return truthy on success
  submitHandler:   { type: Function, default: null },
})

const emit = defineEmits(['update:modelValue', 'created'])

// ── Composables ─────────────────────────────────────────────────────────────
const {
  form, fields, submitting, resetForm, submit,
  loadTags, allTagsList, getTagColor: internalGetTagColor,
  onCreateTag, onUpdateTag, onRenameTag, onDeleteTag,
  parentOptions, searchParent,
  findingBest, ranking, findBestTech,
} = useUnifiedCreate(toRef(props, 'mode'), {
  allTags: props.externalTags,
  getTagColor: props.externalGetColor,
})

const { addrResults, searchAddr, selectAddr } = useAddressSearch()

// Divulgation progressive : on n'affiche d'abord que l'essentiel (sujet · priorité · description). « Plus d'options » révèle le reste.
const showAdvanced = ref(false)

// ── Computed ────────────────────────────────────────────────────────────────
const title = computed(() => {
  const m = props.mode
  if (m === 'ticket') return 'Nouveau ticket'
  if (m === 'task') return 'Nouvelle tâche'
  return 'Nouveau travail de dispatch'
})

const submitLabel = computed(() => {
  if (props.mode === 'ticket') return 'Créer ticket'
  if (props.mode === 'task') return 'Créer tâche'
  return 'Créer travail'
})

const contextLabel = computed(() => {
  const c = props.context
  if (c.source_issue) return c.source_issue
  if (c.customer) return c.customer
  if (c.locationLabel) return c.locationLabel
  return ''
})

const allTagsComputed = computed(() => props.externalTags || allTagsList.value)
const getTagColor = computed(() => props.externalGetColor || internalGetTagColor)

// Priorité Dispatch Job — SOURCE UNIQUE (3 niveaux ; « Urgent » = high, le champ Select rejette 'urgent' → 417).
import { DISPATCH_PRIORITIES as priorityOptions } from 'src/config/dispatch-priority'

// Types de job — SOURCE UNIQUE (config/job-types).
import { JOB_TYPE_OPTIONS as jobTypeOptions } from 'src/config/job-types'

const issueTypeOptions = [
  { label: 'Support', value: 'Support' },
  { label: 'Installation', value: 'Installation' },
  { label: 'Déménagement', value: 'Demenagement' },
  { label: 'Facturation', value: 'Facturation' },
  { label: 'Réseau', value: 'Reseau' },
  { label: 'Autre', value: 'Autre' },
]

const locationOptions = computed(() =>
  (props.locations || []).map(l => ({
    label: l.address_line || l.location_name || l.name,
    value: l.name,
  }))
)

const techOptions = computed(() =>
  (props.technicians || []).map(t => ({
    label: t.full_name || t.fullName || t.name,
    value: t.technician_id || t.id,
  }))
)

const parentOpts = computed(() => parentOptions.value)

// ── Watchers ────────────────────────────────────────────────────────────────
watch(() => props.modelValue, (open) => {
  if (open) {
    resetForm(props.context)
    // Pre-select location if context provides it
    if (props.context.service_location) {
      form.service_location = props.context.service_location
    }
    // Divulgation progressive : ouvrir les options d'emblée SEULEMENT si nécessaires (intervention = adresse+tech) ou déjà pré-remplies par le contexte.
    showAdvanced.value = props.mode === 'work-order' || !!(props.context.service_location || props.context.issue_type || props.context.job_type || props.context.duration_h || props.context.scheduled_date || props.context.depends_on || (props.context.tags && props.context.tags.length))
    // Load tags if in a mode that uses them
    if (fields.value.showTags && !props.externalTags) {
      loadTags()
    }
  }
})

// ── Methods ─────────────────────────────────────────────────────────────────
function onSelectAddr (addr) {
  selectAddr(addr, form)
}

function onParentFilter (val, update) {
  searchParent(val, (results) => {
    update(() => {
      parentOptions.value = results
    })
  })
}

async function onSubmit () {
  if (!form.subject?.trim()) return
  if (props.submitHandler) {
    // Custom handler — pass raw form data, let parent manage store + close
    submitting.value = true
    try {
      const result = await props.submitHandler({ ...form, tags: [...form.tags] })
      if (result !== false) {
        emit('created', result)
        emit('update:modelValue', false)
      }
    } catch (err) {
      Notify.create({ type: 'negative', message: `Erreur: ${err.message || err}` })
    } finally {
      submitting.value = false
    }
    return
  }
  const result = await submit()
  if (result) {
    emit('created', result)
    emit('update:modelValue', false)
  }
}
</script>

<style scoped>
.best-tech-ranking {
  border: 1px solid var(--ops-border, #e2e8f0);
  border-radius: 8px;
  overflow: hidden;
}
.ranking-header {
  background: var(--ops-surface, #f8fafc);
  border-bottom: 1px solid var(--ops-border, #e2e8f0);
}
</style>
