<template>
  <span
    class="inline-field"
    :class="{
      'inline-field--editing': editing,
      'inline-field--saving': saving,
      'inline-field--readonly': readonly,
    }"
    @dblclick.stop="startEdit"
  >
    <!-- Display mode -->
    <template v-if="!editing">
      <slot name="display" :value="value" :display-value="displayValue" :start-edit="startEdit">
        <span class="inline-field__value" :class="{ 'inline-field__placeholder': !displayValue, 'inline-field__value--multiline': type === 'textarea' }">
          {{ displayValue || placeholder }}
        </span>
      </slot>
      <q-spinner v-if="saving" size="12px" color="primary" class="q-ml-xs" />
    </template>

    <!-- Edit mode: text / number -->
    <q-input
      v-else-if="type === 'text' || type === 'number'"
      ref="inputRef"
      v-model="editValue"
      :type="type === 'number' ? 'number' : 'text'"
      dense
      borderless
      :input-class="'inline-field__input'"
      :autofocus="true"
      @keydown.enter.prevent="commitEdit"
      @keydown.esc.prevent="cancelEdit"
      @blur="onBlur"
    />

    <!-- Edit mode: textarea -->
    <q-input
      v-else-if="type === 'textarea'"
      ref="inputRef"
      v-model="editValue"
      type="textarea"
      dense
      borderless
      autogrow
      :input-class="'inline-field__input'"
      :autofocus="true"
      @keydown.esc.prevent="cancelEdit"
      @keydown.ctrl.enter="commitEdit"
      @keydown.meta.enter="commitEdit"
      @blur="onBlur"
    />

    <!-- Edit mode: select -->
    <q-select
      v-else-if="type === 'select'"
      ref="inputRef"
      v-model="editValue"
      :options="options"
      dense
      borderless
      emit-value
      map-options
      :input-class="'inline-field__input'"
      :autofocus="true"
      @update:model-value="commitEdit"
      @keydown.esc.prevent="cancelEdit"
    />

    <!-- Edit mode: date -->
    <q-input
      v-else-if="type === 'date'"
      ref="inputRef"
      v-model="editValue"
      type="date"
      dense
      borderless
      :input-class="'inline-field__input'"
      :autofocus="true"
      @keydown.enter.prevent="commitEdit"
      @keydown.esc.prevent="cancelEdit"
      @blur="onBlur"
    />
  </span>
</template>

<script setup>
import { ref, computed, nextTick } from 'vue'
import { useInlineEdit } from 'src/composables/useInlineEdit'

const props = defineProps({
  /** Current field value */
  value: { type: [String, Number, null], default: '' },
  /** Field name in the doctype */
  field: { type: String, required: true },
  /** ERPNext doctype */
  doctype: { type: String, required: true },
  /** ERPNext document name */
  docname: { type: String, required: true },
  /** Input type: text, number, textarea, select, date */
  type: { type: String, default: 'text' },
  /** Options for select type — array of strings or { label, value } */
  options: { type: Array, default: () => [] },
  /** Placeholder when value is empty */
  placeholder: { type: String, default: '—' },
  /** If true, disable editing */
  readonly: { type: Boolean, default: false },
  /** Custom display formatter */
  formatter: { type: Function, default: null },
})

const emit = defineEmits(['saved', 'editing'])

const editing = ref(false)
const editValue = ref('')
const inputRef = ref(null)
const committing = ref(false) // prevents double-fire from blur + enter/select
const { save, saving } = useInlineEdit()

const displayValue = computed(() => {
  if (props.formatter) return props.formatter(props.value)
  if (props.type === 'select' && props.options.length) {
    const opt = props.options.find(o => (typeof o === 'object' ? o.value : o) === props.value)
    return opt ? (typeof opt === 'object' ? opt.label : opt) : props.value
  }
  return props.value != null && props.value !== '' ? String(props.value) : ''
})

function startEdit () {
  if (props.readonly || editing.value) return
  editValue.value = props.value ?? ''
  editing.value = true
  committing.value = false
  emit('editing', true)
  nextTick(() => {
    const el = inputRef.value
    if (el) {
      if (typeof el.focus === 'function') el.focus()
      if (props.type === 'select' && typeof el.showPopup === 'function') el.showPopup()
    }
  })
}

// Blur handler with small delay to let Enter/select fire first
function onBlur () {
  // Delay so Enter keydown or select @update fires first and sets committing
  setTimeout(() => {
    if (!committing.value && editing.value) commitEdit()
  }, 80)
}

async function commitEdit () {
  if (!editing.value || committing.value) return
  committing.value = true
  const newVal = props.type === 'number' ? Number(editValue.value) : editValue.value
  editing.value = false
  emit('editing', false)

  // Skip save if value unchanged
  if (newVal === props.value) {
    committing.value = false
    return
  }

  const ok = await save(props.doctype, props.docname, props.field, newVal)
  if (ok) {
    emit('saved', { field: props.field, value: newVal, doctype: props.doctype, docname: props.docname })
  }
  committing.value = false
}

function cancelEdit () {
  committing.value = true // prevent blur from firing after cancel
  editing.value = false
  emit('editing', false)
  setTimeout(() => { committing.value = false }, 100)
}

/** Allow parent to trigger edit programmatically */
defineExpose({ startEdit })
</script>

<style lang="scss">
/* Champs multi-lignes (description, notes) : conserver les sauts de ligne en lecture (sinon tout est aplati en un paragraphe) */
.inline-field__value--multiline { white-space: pre-wrap; word-break: break-word; }
.inline-field {
  display: inline-flex;
  align-items: center;
  min-width: 30px;
  border-radius: 4px;
  transition: background 0.15s;
  cursor: default;

  &:not(&--readonly):not(&--editing) {
    cursor: pointer;

    &:hover {
      background: #f1f5f9;
    }
  }

  &--editing {
    background: #e0f2fe;
  }

  &--saving {
    opacity: 0.7;
  }

  &__value {
    padding: 1px 4px;
    min-height: 1.4em;
    line-height: 1.4;
  }

  &__placeholder {
    color: #9e9e9e;
    font-style: italic;
  }

  &__input {
    font-size: inherit !important;
    line-height: 1.4 !important;
    padding: 1px 4px !important;
    min-height: 1.4em !important;
  }

  // Override Quasar input padding when inline
  .q-field__control {
    min-height: unset !important;
    height: auto !important;
    padding: 0 !important;
  }

  .q-field__native {
    padding: 0 !important;
    min-height: unset !important;
  }

  .q-field--dense .q-field__control {
    min-height: unset !important;
  }
}
</style>
