<script setup lang="ts">
/**
 * Right panel: edits the currently-selected element. Shows a common
 * position/size/order block plus a per-type field set. All edits flow through
 * the injected `ldDesigner` with a history entry per change (`commit: true`).
 */
import type {
  LdTextElement, LdBarcodeElement, LdQrElement, LdDataMatrixElement,
  LdImageElement, LdRectElement, LdEllipseElement, LdLineElement
} from '~/composables/useLabelDesign'

const designer = inject('ldDesigner') as ReturnType<typeof useLabelDesign>
const { selected } = designer

const update = (patch: Record<string, any>) => {
  if (selected.value) designer.updateElement(selected.value.id, patch, true)
}

// Live edits for text-entry fields: reflect on the canvas on every keystroke
// (commit:false) but group the whole typing session into a single undo step —
// record one history snapshot on the first input after focus.
let dirtyEdit = false
const beginEdit = () => { dirtyEdit = false }
const live = (patch: Record<string, any>) => {
  if (!selected.value) return
  if (!dirtyEdit) { designer.record(); dirtyEdit = true }
  designer.updateElement(selected.value.id, patch, false)
}

const num = (e: Event) => round2(Number((e.target as HTMLInputElement).value) || 0)
const val = (e: Event) => (e.target as HTMLInputElement).value
const checked = (e: Event) => (e.target as HTMLInputElement).checked

// type-narrowed views
const t = computed(() => (selected.value?.type === 'text' ? selected.value as LdTextElement : null))
const bc = computed(() => (selected.value?.type === 'barcode' ? selected.value as LdBarcodeElement : null))
const qr = computed(() => (selected.value?.type === 'qr' ? selected.value as LdQrElement : null))
const dm = computed(() => (selected.value?.type === 'datamatrix' ? selected.value as LdDataMatrixElement : null))
const img = computed(() => (selected.value?.type === 'image' ? selected.value as LdImageElement : null))
const rc = computed(() => (selected.value?.type === 'rect' ? selected.value as LdRectElement : null))
const el2 = computed(() => (selected.value?.type === 'ellipse' ? selected.value as LdEllipseElement : null))
const ln = computed(() => (selected.value?.type === 'line' ? selected.value as LdLineElement : null))

const colorVal = (c?: string) => (!c || c === 'transparent' || c === 'none' ? '#ffffff' : c)

const replaceInput = ref<HTMLInputElement | null>(null)
const onReplace = (e: Event) => {
  const file = (e.target as HTMLInputElement).files?.[0]
  if (!file) return
  const reader = new FileReader()
  reader.onload = () => update({ dataUrl: String(reader.result || '') })
  reader.readAsDataURL(file)
  ;(e.target as HTMLInputElement).value = ''
}

const dashOn = computed(() => !!(ln.value?.dash && ln.value.dash.length))
</script>

<template>
  <div class="ldProps">
    <p class="ldProps__title">Properties</p>

    <div v-if="!selected" class="ldProps__empty">
      Select an element on the label to edit its properties.
    </div>

    <template v-else>
      <!-- COMMON -->
      <div class="ldProps__section">
        <div class="ldField">
          <label>Layer name <span class="ldNote">(not printed)</span></label>
          <input class="input is-small" :value="selected.name" @focus="beginEdit" @input="live({ name: val($event) })" />
        </div>
        <div class="ldGrid2">
          <div class="ldField"><label>X (mm)</label><input type="number" step="0.5" class="input is-small" :value="selected.x" @change="update({ x: num($event) })" /></div>
          <div class="ldField"><label>Y (mm)</label><input type="number" step="0.5" class="input is-small" :value="selected.y" @change="update({ y: num($event) })" /></div>
          <div class="ldField"><label>{{ ln ? 'ΔX (mm)' : 'Width (mm)' }}</label><input type="number" step="0.5" class="input is-small" :value="selected.w" @change="update({ w: num($event) })" /></div>
          <div class="ldField"><label>{{ ln ? 'ΔY (mm)' : 'Height (mm)' }}</label><input type="number" step="0.5" class="input is-small" :value="selected.h" @change="update({ h: num($event) })" /></div>
        </div>
        <div class="ldProps__actions">
          <button type="button" class="button is-small" title="Bring to front" @click="designer.bringToFront(selected.id)"><span class="ti ti-stack-front"></span></button>
          <button type="button" class="button is-small" title="Send to back" @click="designer.sendToBack(selected.id)"><span class="ti ti-stack-back"></span></button>
          <button type="button" class="button is-small" title="Duplicate" @click="designer.duplicateElement(selected.id)"><span class="ti ti-copy"></span></button>
          <button type="button" class="button is-small is-danger is-light" title="Delete" @click="designer.removeElement(selected.id)"><span class="ti ti-trash"></span></button>
        </div>
      </div>

      <!-- TEXT -->
      <div v-if="t" class="ldProps__section">
        <div class="ldField"><label>Text <span class="ldNote">(printed content)</span></label><textarea class="textarea is-small" rows="3" :value="t.text" @focus="beginEdit" @input="live({ text: val($event) })"></textarea></div>
        <div class="ldGrid2">
          <div class="ldField">
            <label>Font</label>
            <div class="select is-small is-fullwidth"><select :value="t.fontFamily" @change="update({ fontFamily: val($event) })"><option value="helvetica">Helvetica</option><option value="times">Times</option><option value="courier">Courier</option></select></div>
          </div>
          <div class="ldField"><label>Size (pt)</label><input type="number" step="0.5" min="3" class="input is-small" :value="t.fontSizePt" @change="update({ fontSizePt: num($event) })" /></div>
          <div class="ldField">
            <label>Style</label>
            <div class="select is-small is-fullwidth"><select :value="t.fontStyle" @change="update({ fontStyle: val($event) })"><option value="normal">Normal</option><option value="bold">Bold</option><option value="italic">Italic</option><option value="bolditalic">Bold Italic</option></select></div>
          </div>
          <div class="ldField"><label>Color</label><input type="color" class="ldColor" :value="t.color" @change="update({ color: val($event) })" /></div>
          <div class="ldField">
            <label>Align</label>
            <div class="select is-small is-fullwidth"><select :value="t.align" @change="update({ align: val($event) })"><option value="left">Left</option><option value="center">Center</option><option value="right">Right</option></select></div>
          </div>
          <div class="ldField">
            <label>V-Align</label>
            <div class="select is-small is-fullwidth"><select :value="t.vAlign" @change="update({ vAlign: val($event) })"><option value="top">Top</option><option value="middle">Middle</option><option value="bottom">Bottom</option></select></div>
          </div>
          <div class="ldField"><label>Line height</label><input type="number" step="0.05" min="0.6" class="input is-small" :value="t.lineHeight" @change="update({ lineHeight: num($event) })" /></div>
          <div class="ldField"><label>Letter sp. (pt)</label><input type="number" step="0.1" class="input is-small" :value="t.letterSpacingPt" @change="update({ letterSpacingPt: num($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="t.wrap" @change="update({ wrap: checked($event) })" /> Wrap text to width</label>
      </div>

      <!-- BARCODE -->
      <div v-else-if="bc" class="ldProps__section">
        <div class="ldField">
          <label>Symbology</label>
          <div class="select is-small is-fullwidth"><select :value="bc.symbology" @change="update({ symbology: val($event) })">
            <option value="code128">Code 128</option><option value="code39">Code 39</option><option value="ean13">EAN-13</option><option value="ean8">EAN-8</option><option value="upca">UPC-A</option><option value="itf14">ITF-14</option><option value="gs1-128">GS1-128</option>
          </select></div>
        </div>
        <div class="ldField"><label>Value</label><input class="input is-small" :value="bc.value" @focus="beginEdit" @input="live({ value: val($event) })" /></div>
        <label class="ldCheck"><input type="checkbox" :checked="bc.showText" @change="update({ showText: checked($event) })" /> Show value text</label>
        <div class="ldGrid2">
          <div class="ldField"><label>Bars</label><input type="color" class="ldColor" :value="bc.barColor" @change="update({ barColor: val($event) })" /></div>
          <div class="ldField"><label>Background</label><input type="color" class="ldColor" :value="colorVal(bc.bgColor)" :disabled="bc.bgColor === 'transparent'" @change="update({ bgColor: val($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="bc.bgColor === 'transparent'" @change="update({ bgColor: checked($event) ? 'transparent' : '#ffffff' })" /> Transparent background</label>
      </div>

      <!-- QR -->
      <div v-else-if="qr" class="ldProps__section">
        <div class="ldField"><label>Value</label><textarea class="textarea is-small" rows="2" :value="qr.value" @focus="beginEdit" @input="live({ value: val($event) })"></textarea></div>
        <div class="ldGrid2">
          <div class="ldField">
            <label>Error correction</label>
            <div class="select is-small is-fullwidth"><select :value="qr.eccLevel" @change="update({ eccLevel: val($event) })"><option value="L">L (7%)</option><option value="M">M (15%)</option><option value="Q">Q (25%)</option><option value="H">H (30%)</option></select></div>
          </div>
          <div class="ldField"><label>Modules</label><input type="color" class="ldColor" :value="qr.barColor" @change="update({ barColor: val($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="qr.bgColor === 'transparent'" @change="update({ bgColor: checked($event) ? 'transparent' : '#ffffff' })" /> Transparent background</label>
      </div>

      <!-- DATAMATRIX -->
      <div v-else-if="dm" class="ldProps__section">
        <div class="ldField"><label>Value</label><textarea class="textarea is-small" rows="2" :value="dm.value" @focus="beginEdit" @input="live({ value: val($event) })"></textarea></div>
        <div class="ldGrid2">
          <div class="ldField"><label>Modules</label><input type="color" class="ldColor" :value="dm.barColor" @change="update({ barColor: val($event) })" /></div>
          <div class="ldField"><label>Background</label><input type="color" class="ldColor" :value="colorVal(dm.bgColor)" :disabled="dm.bgColor === 'transparent'" @change="update({ bgColor: val($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="dm.bgColor === 'transparent'" @change="update({ bgColor: checked($event) ? 'transparent' : '#ffffff' })" /> Transparent background</label>
      </div>

      <!-- IMAGE -->
      <div v-else-if="img" class="ldProps__section">
        <button type="button" class="button is-small is-fullwidth" @click="replaceInput?.click()"><span class="ti ti-upload mr-1"></span> Replace image</button>
        <input ref="replaceInput" type="file" accept="image/*" class="is-hidden" @change="onReplace" />
        <div class="ldField">
          <label>Fit</label>
          <div class="select is-small is-fullwidth"><select :value="img.fit" @change="update({ fit: val($event) })"><option value="contain">Contain</option><option value="cover">Cover</option><option value="fill">Stretch</option></select></div>
        </div>
        <div class="ldField"><label>Opacity ({{ Math.round((img.opacity ?? 1) * 100) }}%)</label><input type="range" min="0" max="1" step="0.05" :value="img.opacity ?? 1" @input="update({ opacity: Number(val($event)) })" /></div>
      </div>

      <!-- RECT -->
      <div v-else-if="rc" class="ldProps__section">
        <div class="ldGrid2">
          <div class="ldField"><label>Fill</label><input type="color" class="ldColor" :value="colorVal(rc.fill)" :disabled="rc.fill === 'transparent'" @change="update({ fill: val($event) })" /></div>
          <div class="ldField"><label>Stroke</label><input type="color" class="ldColor" :value="colorVal(rc.stroke)" :disabled="rc.stroke === 'transparent'" @change="update({ stroke: val($event) })" /></div>
          <div class="ldField"><label>Stroke (mm)</label><input type="number" step="0.1" min="0" class="input is-small" :value="rc.strokeWidthMm" @change="update({ strokeWidthMm: num($event) })" /></div>
          <div class="ldField"><label>Radius (mm)</label><input type="number" step="0.2" min="0" class="input is-small" :value="rc.radiusMm" @change="update({ radiusMm: num($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="rc.fill === 'transparent'" @change="update({ fill: checked($event) ? 'transparent' : '#ffffff' })" /> Transparent fill</label>
        <label class="ldCheck"><input type="checkbox" :checked="rc.stroke === 'transparent'" @change="update({ stroke: checked($event) ? 'transparent' : '#000000' })" /> No border</label>
      </div>

      <!-- ELLIPSE -->
      <div v-else-if="el2" class="ldProps__section">
        <div class="ldGrid2">
          <div class="ldField"><label>Fill</label><input type="color" class="ldColor" :value="colorVal(el2.fill)" :disabled="el2.fill === 'transparent'" @change="update({ fill: val($event) })" /></div>
          <div class="ldField"><label>Stroke</label><input type="color" class="ldColor" :value="colorVal(el2.stroke)" :disabled="el2.stroke === 'transparent'" @change="update({ stroke: val($event) })" /></div>
          <div class="ldField"><label>Stroke (mm)</label><input type="number" step="0.1" min="0" class="input is-small" :value="el2.strokeWidthMm" @change="update({ strokeWidthMm: num($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="el2.fill === 'transparent'" @change="update({ fill: checked($event) ? 'transparent' : '#ffffff' })" /> Transparent fill</label>
        <label class="ldCheck"><input type="checkbox" :checked="el2.stroke === 'transparent'" @change="update({ stroke: checked($event) ? 'transparent' : '#000000' })" /> No border</label>
      </div>

      <!-- LINE -->
      <div v-else-if="ln" class="ldProps__section">
        <div class="ldGrid2">
          <div class="ldField"><label>Color</label><input type="color" class="ldColor" :value="ln.stroke" @change="update({ stroke: val($event) })" /></div>
          <div class="ldField"><label>Width (mm)</label><input type="number" step="0.1" min="0.1" class="input is-small" :value="ln.strokeWidthMm" @change="update({ strokeWidthMm: num($event) })" /></div>
        </div>
        <label class="ldCheck"><input type="checkbox" :checked="dashOn" @change="update({ dash: checked($event) ? [2, 1] : [] })" /> Dashed</label>
      </div>
    </template>
  </div>
</template>

<style scoped>
.ldProps { padding: 12px; display: flex; flex-direction: column; gap: 14px; }
.ldProps__title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.55; }
.ldProps__empty { font-size: 13px; opacity: 0.6; padding: 8px 2px; }
.ldProps__section { display: flex; flex-direction: column; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid var(--theme-border, #ececef); }
.ldProps__section:last-child { border-bottom: none; }
.ldProps__actions { display: flex; gap: 6px; }
.ldGrid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ldField { display: flex; flex-direction: column; gap: 3px; }
.ldField > label { font-size: 11px; opacity: 0.7; }
.ldNote { opacity: 0.55; font-style: italic; }
.ldColor { width: 100%; height: 30px; border: 1px solid var(--theme-border, #e2e2e6); border-radius: 6px; background: none; cursor: pointer; padding: 2px; }
.ldCheck { display: flex; align-items: center; gap: 7px; font-size: 12px; cursor: pointer; }
.ldCheck input { margin: 0; }
</style>
