<script setup lang="ts">
// <!-- ld-v2 --> Un curseur du Réglage collectif : libellé métier, valeur en 700,
// statu quo losange creux, alternative clavier + champ numérique, poignée ≥2.25rem.
// Faisceau strip-plot : points translucides anonymes, médiane trait épais,
// baseline marqueur creux. Part « calculé » : rail estompé, jamais saisissable.
import { BIMODAL_BANNER, PARAM_DERIVED_LABEL } from '~/lexicon'
import type { ParamDef } from '~/types/domain'

const props = defineProps<{
  param: ParamDef
  value: number
  dots?: number[]
  median?: number
  locked?: boolean
  neutral?: boolean
  bimodal?: boolean
}>()
const emit = defineEmits<{ (e: 'update:value', v: number): void }>()

function frac(v: number): number {
  const span = props.param.max - props.param.min
  if (span <= 0) return 0
  return Math.min(1, Math.max(0, (v - props.param.min) / span))
}
function fmt(v: number): string {
  return v.toLocaleString('fr-FR', { maximumFractionDigits: 2 })
}
function onInput(event: Event) {
  const raw = Number((event.target as HTMLInputElement).value)
  if (Number.isFinite(raw)) emit('update:value', raw)
}
const inputId = `vps-${props.param.key}-${Math.random().toString(36).slice(2, 7)}`
</script>

<template>
  <!-- ld-v2 -->
  <div class="vps" :class="{ 'vps--derived': param.derived, 'vps--neutral': neutral, 'vps--locked': locked }">
    <div class="vps__head">
      <label class="vps__label" :for="inputId">{{ param.label }}</label>
      <span v-if="param.derived" class="vps__tag">{{ PARAM_DERIVED_LABEL }}</span>
      <span class="vps__value">
        {{ fmt(value) }}<span v-if="param.unit" class="vps__unit">&nbsp;{{ param.unit }}</span>
      </span>
    </div>

    <div class="vps__row">
      <div class="vps__rail-zone">
        <!-- Faisceau + repères, calés sur la course utile de la poignée -->
        <div class="vps__overlay" aria-hidden="true">
          <span
            v-for="(dot, i) in dots ?? []"
            :key="i"
            class="vps__dot"
            :style="{ '--p': frac(dot) }"
          />
          <span
            v-if="param.baseline !== undefined"
            class="vps__baseline"
            :style="{ '--p': frac(param.baseline) }"
            :title="`Aujourd'hui : ${fmt(param.baseline)}`"
          />
          <span
            v-if="median !== undefined"
            class="vps__median"
            :style="{ '--p': frac(median) }"
            :title="`Médiane : ${fmt(median)}`"
          />
        </div>
        <input
          v-if="!param.derived"
          :id="inputId"
          class="vps__range"
          type="range"
          :min="param.min"
          :max="param.max"
          :step="param.step"
          :value="value"
          :disabled="locked"
          :aria-label="param.label"
          @input="onInput"
        >
        <div v-else class="vps__ghost">
          <div class="vps__ghost-fill" :style="{ width: `${frac(value) * 100}%` }" />
        </div>
      </div>
      <input
        v-if="!param.derived"
        class="vps__num"
        type="number"
        :min="param.min"
        :max="param.max"
        :step="param.step"
        :value="value"
        :disabled="locked"
        :aria-label="`${param.label} — saisie directe`"
        @change="onInput"
      >
    </div>

    <p v-if="bimodal" class="vps__bimodal">
      <UIcon name="i-lucide-split" />
      <span>{{ BIMODAL_BANNER(param.label) }}</span>
    </p>
  </div>
</template>

<style scoped>
.vps { display: flex; flex-direction: column; gap: 0.2rem; --vps-accent: var(--mood-accent); }
.vps--neutral { --vps-accent: var(--mood-text-muted); }
.vps__head { display: flex; align-items: baseline; gap: 0.5rem; }
.vps__label { font-size: 0.9375rem; font-weight: 600; }
.vps__tag {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--mood-text-muted); background: var(--mood-bg);
  padding: 1px 8px; border-radius: var(--r-pill);
}
.vps__value { margin-left: auto; font-weight: 700; font-size: 1.0625rem; color: var(--vps-accent); }
.vps__unit { font-size: 0.8125rem; font-weight: 600; color: var(--mood-text-muted); }
.vps__row { display: flex; align-items: center; gap: 0.75rem; }
.vps__rail-zone { position: relative; flex: 1; min-width: 0; }

/* Faisceau et repères : course utile = largeur − poignée (2.25rem) */
.vps__overlay { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.vps__overlay > * { position: absolute; top: 50%; left: calc(1.125rem + (100% - 2.25rem) * var(--p)); }
.vps__dot {
  width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  background: var(--vps-accent); opacity: 0.25;
}
.vps__median {
  width: 4px; height: 20px; margin: -10px 0 0 -2px; border-radius: 2px;
  background: var(--vps-accent);
}
.vps__baseline {
  width: 10px; height: 10px; margin: -5px 0 0 -5px;
  transform: rotate(45deg);
  background: var(--mood-surface);
  box-shadow: inset 0 0 0 2px var(--mood-text-muted);
}

/* Poignée tactile ≥ 2.25rem, clavier natif */
.vps__range {
  appearance: none; -webkit-appearance: none;
  display: block; width: 100%; height: 2.5rem;
  background: transparent; cursor: pointer; position: relative; z-index: 2;
}
.vps__range:disabled { cursor: not-allowed; opacity: 0.6; }
.vps__range::-webkit-slider-runnable-track {
  height: 8px; border-radius: 4px;
  background: color-mix(in srgb, var(--vps-accent) 18%, var(--mood-bg));
}
.vps__range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 2.25rem; height: 2.25rem; margin-top: -14px;
  border-radius: 50%;
  background: radial-gradient(circle at center, var(--vps-accent) 0 7px, color-mix(in srgb, var(--vps-accent) 22%, var(--mood-surface)) 8px);
  box-shadow: 0 1px 4px var(--mood-shadow);
}
.vps__range::-moz-range-track {
  height: 8px; border-radius: 4px;
  background: color-mix(in srgb, var(--vps-accent) 18%, var(--mood-bg));
}
.vps__range::-moz-range-thumb {
  width: 2.25rem; height: 2.25rem; border: none; border-radius: 50%;
  background: radial-gradient(circle at center, var(--vps-accent) 0 7px, color-mix(in srgb, var(--vps-accent) 22%, var(--mood-surface)) 8px);
  box-shadow: 0 1px 4px var(--mood-shadow);
}

/* Part calculée : rail estompé, non saisissable */
.vps__ghost {
  height: 8px; margin: 1.05rem 1.125rem;
  border-radius: 4px; background: var(--mood-bg); opacity: 0.75; overflow: hidden;
}
.vps__ghost-fill { height: 100%; background: color-mix(in srgb, var(--mood-text-muted) 35%, transparent); transition: width 0.15s ease; }
.vps--derived .vps__value { color: var(--mood-text-muted); }

.vps__num {
  width: 5.25rem; min-height: 2.25rem; padding: 0.25rem 0.5rem;
  font-size: 0.9375rem; font-weight: 600; text-align: right;
  box-shadow: inset 0 0 0 1.5px var(--mood-input-border);
}
.vps__num:focus-visible { box-shadow: inset 0 0 0 1.5px var(--mood-input-focus); }

.vps__bimodal {
  display: flex; align-items: baseline; gap: 0.4rem; margin: 0.15rem 0 0;
  font-size: 0.8125rem; font-weight: 600; color: var(--mood-warning);
  background: var(--mood-status-fenetre-bg); border-radius: var(--r-input); padding: 0.4rem 0.65rem;
}
</style>
