<script setup>
/**
 * FBA-relabel label printing (sales-order edit page, post-completion).
 *
 * Prints one label per unit for every order line: CODE128 barcode from
 * C_OrderLine.printLabelCode + article name + code cleartext + "Label auf
 * SKU: …" hint. The user picks the target label printer (CUST_Printer
 * registry via GET /api/printers) AND the label size — the server layout
 * (/api/print/relabel-labels) adapts dynamically to any w×h.
 */
import { toast } from 'bulma-toast'
import { LABEL_SIZE_PRESETS } from '~/composables/useLabelDesign'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  orderId: {
    type: [String, Number],
    default: ''
  },
  documentNo: {
    type: String,
    default: ''
  }
})

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

const { t } = useTranslation()
const { fetchRelabelRows, generateBarcodeDataUrl } = useRelabelDocs()

const DEFAULT_PRINTERS = ['labelprinter-1', 'labelprinter-2', 'labelprinter-3', 'labelprinter-4', 'labelprinter-5', 'labelprinter-6']

const rows = ref([])
const loadingRows = ref(false)
const busy = ref(false)

const printers = ref([])
const printerValue = ref('')
const customPrinter = ref('')
const printOptions = ref('')
const printerOptionsByName = ref({})
let lastAutoOptions = ''

const applyPrinterDefaults = (cups) => {
  const def = printerOptionsByName.value[cups] || ''
  if (printOptions.value === '' || printOptions.value === lastAutoOptions) {
    printOptions.value = def
    lastAutoOptions = def
  }
}

const fetchPrinters = async () => {
  try {
    const res = await $fetch('/api/printers', { headers: useRequestHeaders(['cookie']) })
    const recs = Array.isArray(res?.records) ? res.records : []
    const seen = new Set()
    const list = []
    const optsMap = {}
    let preferred = ''
    // Label printers ('lab') first — that's what these labels are for.
    const sorted = [...recs].sort((a, b) => (a?.printerType === 'lab' ? 0 : 1) - (b?.printerType === 'lab' ? 0 : 1))
    for (const r of sorted) {
      const cups = r?.cupsName
      if (!cups || seen.has(cups)) continue
      seen.add(cups)
      const typeTag = r?.printerTypeLabel ? ` · ${r.printerTypeLabel}` : ''
      list.push({ name: `${r.name || cups} (${cups})${typeTag}`, value: cups })
      optsMap[cups] = r?.defaultPrintOptions || ''
      if (r?.isDefault && r?.printerType === 'lab' && !preferred) preferred = cups
      if (r?.isDefault && !preferred) preferred = cups
    }
    if (list.length) {
      printers.value = list
      printerOptionsByName.value = optsMap
      if (!printerValue.value || (printerValue.value !== '__custom__' && !seen.has(printerValue.value))) {
        printerValue.value = preferred || list[0].value
      }
    } else {
      printers.value = DEFAULT_PRINTERS.map(p => ({ name: p, value: p }))
      printerOptionsByName.value = {}
      if (!printerValue.value) printerValue.value = printers.value[0].value
    }
  } catch {
    printers.value = DEFAULT_PRINTERS.map(p => ({ name: p, value: p }))
    printerOptionsByName.value = {}
    if (!printerValue.value) printerValue.value = printers.value[0].value
  }
  applyPrinterDefaults(printerValue.value)
}

watch(printerValue, (v) => { if (v && v !== '__custom__') applyPrinterDefaults(v) })

// Label size: presets from the label designer + free custom w×h (mm)
const sizeChoice = ref('57x32')
const customW = ref(57)
const customH = ref(32)
const sizeOptions = computed(() => [
  ...LABEL_SIZE_PRESETS.map(p => ({ name: p.name, value: `${p.wMm}x${p.hMm}` })),
  { name: t.value?.custom_size || 'Eigene Größe…', value: '__custom__' }
])
const size = computed(() => {
  if (sizeChoice.value === '__custom__') {
    return { w: Number(customW.value) || 57, h: Number(customH.value) || 32 }
  }
  const [w, h] = sizeChoice.value.split('x').map(Number)
  return { w, h }
})

const resolvedPrinter = computed(() => (printerValue.value === '__custom__' ? customPrinter.value.trim() : printerValue.value))
const totalLabels = computed(() => rows.value.reduce((acc, r) => acc + Number(r.qty || 0), 0))

const loadRows = async () => {
  loadingRows.value = true
  try {
    rows.value = await fetchRelabelRows(props.orderId)
  } catch (e) {
    rows.value = []
    console.error('Failed to load relabel rows:', e)
  }
  loadingRows.value = false
}

watch(() => props.modelValue, (open) => {
  if (open) {
    loadRows()
    fetchPrinters()
  }
})

const close = () => emit('update:modelValue', false)

const stamp = () => new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14)

const submit = async (downloadOnly = false) => {
  const printable = rows.value.filter(r => r.code)
  if (!printable.length) {
    toast({ message: t.value?.relabel_missing_codes || 'Etiketten-Codes fehlen auf Positionen', type: 'is-danger', duration: 3000 })
    return
  }
  if (!downloadOnly && !resolvedPrinter.value) {
    toast({ message: 'Bitte einen Drucker wählen.', type: 'is-danger', duration: 3000 })
    return
  }
  busy.value = true
  try {
    const labels = []
    for (const r of printable) {
      labels.push({ ...r, barcode: await generateBarcodeDataUrl(r.code) })
    }
    const res = await $fetch('/api/print/relabel-labels', {
      method: 'POST',
      headers: useRequestHeaders(['cookie']),
      body: {
        pathName: `relabel-labels/${new Date().getFullYear()}`,
        fileName: `${props.documentNo || props.orderId}-FBA-RELABEL-${stamp()}.pdf`,
        printer: resolvedPrinter.value,
        printOptions: printOptions.value || '',
        size: size.value,
        downloadOnly,
        labels
      }
    })
    if (downloadOnly) {
      if (res?.content) {
        const byteChars = atob(res.content)
        const bytes = new Uint8Array(byteChars.length)
        for (let i = 0; i < byteChars.length; i++) bytes[i] = byteChars.charCodeAt(i)
        const blob = new Blob([bytes], { type: 'application/pdf' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = `${props.documentNo || props.orderId}-FBA-RELABEL-${stamp()}.pdf`
        link.click()
        URL.revokeObjectURL(link.href)
        close()
      } else {
        toast({ message: res?.message || 'PDF generation failed', type: 'is-danger', duration: 3000 })
      }
    } else if (res?.printOk) {
      toast({ message: `${totalLabels.value} Etiketten an ${resolvedPrinter.value} gesendet.`, type: 'is-success', duration: 3000 })
      close()
    } else {
      toast({ message: res?.printResult?.error || res?.printResult?.stderr || res?.message || 'Print failed', type: 'is-danger', duration: 4000 })
    }
  } catch (err) {
    toast({ message: err?.message || 'Print failed', type: 'is-danger', duration: 3000 })
  } finally {
    busy.value = false
  }
}
</script>

<template>
  <Teleport to="body">
    <div v-if="modelValue" class="rlp-overlay" @click.self="close">
      <div class="rlp-dialog">
        <h3 class="rlp-title">
          <span class="tf-icon ti ti-tags ti-sm me-1"></span>
          {{ t?.print_fba_labels || 'FBA-Etiketten drucken' }}
        </h3>
        <p class="rlp-sub">{{ documentNo }} — {{ totalLabels }} {{ t?.labels || 'Etiketten' }} ({{ rows.length }} {{ t?.positions || 'Positionen' }})</p>

        <div v-if="loadingRows" class="rlp-loading">…</div>
        <template v-else>
          <div class="rlp-field">
            <label class="label">{{ t?.printer || 'Drucker' }}</label>
            <div class="select is-fullwidth">
              <select v-model="printerValue">
                <option v-for="p in printers" :key="p.value" :value="p.value">{{ p.name }}</option>
                <option value="__custom__">Custom…</option>
              </select>
            </div>
            <input v-if="printerValue === '__custom__'" v-model="customPrinter" type="text" class="input mt-1" placeholder="CUPS printer name" />
          </div>

          <div class="rlp-field">
            <label class="label">{{ t?.label_size || 'Etikettengröße' }}</label>
            <div class="select is-fullwidth">
              <select v-model="sizeChoice">
                <option v-for="s in sizeOptions" :key="s.value" :value="s.value">{{ s.name }}</option>
              </select>
            </div>
            <div v-if="sizeChoice === '__custom__'" class="rlp-size-inputs">
              <input v-model.number="customW" type="number" min="20" max="300" class="input" placeholder="Breite (mm)" />
              <span>×</span>
              <input v-model.number="customH" type="number" min="20" max="300" class="input" placeholder="Höhe (mm)" />
              <span>mm</span>
            </div>
          </div>

          <div class="rlp-field">
            <label class="label">Print options</label>
            <input v-model="printOptions" type="text" class="input" placeholder="-o fit-to-page" />
          </div>

          <div class="rlp-preview">
            <div v-for="(row, index) in rows" :key="index" class="rlp-preview-row" :class="{ 'rlp-preview-row--missing': !row.code }">
              <span class="rlp-preview-qty">{{ row.qty }}×</span>
              <span class="rlp-preview-code">{{ row.code || '—' }}</span>
              <span class="rlp-preview-sku">{{ t?.label_on_sku || 'Label auf SKU' }}: {{ row.sku }}</span>
            </div>
          </div>
        </template>

        <div class="rlp-actions">
          <button type="button" class="button" :disabled="busy" @click="close">{{ t?.cancel || 'Abbrechen' }}</button>
          <button type="button" class="button" :class="{ 'is-loading': busy }" :disabled="busy || loadingRows" @click="submit(true)">
            <span class="tf-icon ti ti-download ti-xs me-1"></span>
            {{ t?.download || 'Download' }}
          </button>
          <button type="button" class="button is-primary" :class="{ 'is-loading': busy }" :disabled="busy || loadingRows" @click="submit(false)">
            <span class="tf-icon ti ti-printer ti-xs me-1"></span>
            {{ t?.print || 'Drucken' }}
          </button>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<!-- Teleported markup — styles must be non-scoped (teleport + scoped CSS is unreliable) -->
<style>
.rlp-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(15, 23, 42, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.rlp-dialog {
  background: var(--theme-bg-primary, #fff);
  color: var(--theme-text-primary, #0f172a);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  width: min(560px, 100%);
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px 22px;
}
.rlp-title { font-size: 1.1rem; font-weight: 700; display: flex; align-items: center; }
.rlp-sub { font-size: 0.85rem; color: var(--theme-text-secondary, #64748b); margin-bottom: 14px; }
.rlp-field { margin-bottom: 12px; }
.rlp-field .select, .rlp-field select { width: 100%; }
.rlp-size-inputs { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.rlp-size-inputs .input { max-width: 110px; }
.rlp-loading { text-align: center; padding: 24px; }
.rlp-preview {
  border: 1px solid var(--theme-border, #e2e8f0);
  border-radius: 8px;
  max-height: 180px;
  overflow-y: auto;
  margin-top: 4px;
  font-size: 0.8rem;
}
.rlp-preview-row {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 6px 10px;
  border-bottom: 1px solid var(--theme-border, #e2e8f0);
}
.rlp-preview-row:last-child { border-bottom: none; }
.rlp-preview-row--missing { color: #dc2626; }
.rlp-preview-qty { font-weight: 700; min-width: 34px; }
.rlp-preview-code { font-weight: 700; font-family: monospace; }
.rlp-preview-sku { color: var(--theme-text-secondary, #64748b); margin-left: auto; }
.rlp-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
[data-mode="dark"] .rlp-dialog { background: var(--theme-bg-primary, #1e293b); }
</style>
