<template>
  <div>
    <!-- Controls (never printed) -->
    <div class="no-print">
      <div class="controls">
        <h3>Print Asset Label</h3>
        <div v-if="loading" class="loading-msg">Loading...</div>
        <div v-else-if="!asset" class="error-msg">Asset not found</div>
        <template v-else>
          <div class="control-row">
            <label>Style
              <select v-model="style">
                <option value="card">Card (badge)</option>
                <option value="plain">Plain (code only)</option>
              </select>
            </label>
            <label>Code type
              <select v-model="codetype">
                <option value="qr">QR code</option>
                <option value="barcode">Barcode (CODE128)</option>
              </select>
            </label>
            <label>Encodes
              <select v-model="encodes">
                <option value="assetpage">Asset page (link)</option>
                <option value="assetnumber">Asset number</option>
                <option value="serialnumber">Serial number</option>
                <option v-if="hasLocation" value="location">Inspection location code</option>
                <option value="custom">Custom target (settings template)</option>
              </select>
            </label>
          </div>
          <p v-if="encodes === 'location' && !asset.locationcode" class="control-note">
            This tool has no location; the label falls back to the asset page.
          </p>
          <div class="control-row">
            <label>Output
              <select v-model="outputMode">
                <option value="single">Single label (standalone)</option>
                <option value="uline-sheet">Place on ULINE 6-up sheet</option>
              </select>
            </label>
          </div>
          <!-- Cell picker: pick which cell of a partially-used ULINE sheet gets -->
          <!-- this one label. 2x3 grid mirrors the physical cell positions. -->
          <div v-if="outputMode === 'uline-sheet'" class="cell-picker">
            <span class="cell-picker-label">Sheet cell</span>
            <div class="cell-grid">
              <button
                v-for="cellNum in 6"
                :key="cellNum"
                type="button"
                class="cell-btn"
                :class="{ active: cellNum === sheetCell }"
                @click="sheetCell = cellNum"
              >{{ cellNum }}</button>
            </div>
          </div>
          <button class="print-btn" @click="print">Print</button>
        </template>
      </div>
    </div>

    <!-- Printable area: standalone single label (unchanged default). -->
    <div v-if="asset && outputMode === 'single'" class="label-sheet">
      <div class="asset-label" :class="style">
        <template v-if="style === 'card'">
          <div class="label-title">{{ cardTitle }}</div>
          <img v-if="imageUrl" class="label-image" :src="imageUrl" :alt="cardTitle" />
          <div class="label-fields">
            <div v-for="field in identityFields" :key="field.label" class="label-field">
              <span class="field-label">{{ field.label }}</span>
              <span class="field-value">{{ field.value }}</span>
            </div>
          </div>
        </template>
        <div class="code-area">
          <template v-if="codeText">
            <img v-if="codetype === 'qr' && qrImage" class="code-qr" :src="qrImage" alt="QR" />
            <svg v-show="codetype === 'barcode'" ref="barcodeEl" class="code-barcode"></svg>
            <div class="code-caption">{{ caption }}</div>
          </template>
          <div v-else class="code-missing">No {{ encodeLabel }} recorded for this asset.</div>
        </div>
      </div>
    </div>

    <!-- One label placed at the chosen cell of a ULINE 6-up sheet, other five -->
    <!-- blank, so it lands on the right spot of a partially-used sheet. Cell -->
    <!-- layout/CSS replicated from AssetLabelBatch (left untouched) to keep -->
    <!-- batch's verified rendering isolated. Only one branch renders at a time -->
    <!-- so the shared barcodeEl ref resolves to whichever label is live. -->
    <div v-else-if="asset" class="sheets-container">
      <div class="print-sheet">
        <div class="sheet-label no-print">ULINE 6-up sheet - cell {{ sheetCell }}</div>
        <div
          v-for="cellNum in 6"
          :key="cellNum"
          class="label"
          :class="[`pos-${cellNum}`, cellNum === sheetCell ? 'active' : 'inactive']"
        >
          <div v-if="cellNum === sheetCell" class="asset-label in-cell" :class="style">
            <template v-if="style === 'card'">
              <div class="label-title">{{ cardTitle }}</div>
              <img v-if="imageUrl" class="label-image" :src="imageUrl" :alt="cardTitle" />
              <div class="label-fields">
                <div v-for="field in identityFields" :key="field.label" class="label-field">
                  <span class="field-label">{{ field.label }}</span>
                  <span class="field-value">{{ field.value }}</span>
                </div>
              </div>
            </template>
            <div class="code-area">
              <template v-if="codeText">
                <img v-if="codetype === 'qr' && qrImage" class="code-qr" :src="qrImage" alt="QR" />
                <svg v-show="codetype === 'barcode'" ref="barcodeEl" class="code-barcode"></svg>
                <div class="code-caption">{{ caption }}</div>
              </template>
              <div v-else class="code-missing">No {{ encodeLabel }} recorded for this asset.</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { renderQrDataUrl, barcodeInto } from '@/utils/codes'
import { getSetting } from '@/utils/siteSettings'
import { withBase } from '@/utils/basePath'
import {
  TYPE_CONFIG, hasLocationType, resolveDefaultEncodes,
  effectiveEncodes as effEncodes, resolveCodeText as resolveText, captionFor,
} from './assetLabel'

const route = useRoute()
const assettype = route.params.assettype
const config = TYPE_CONFIG[assettype] || null

const loading = ref(true)
const asset = ref(null)
const barcodeEl = ref(null)
const qrImage = ref('')
// The resolved string the code encodes; empty when the chosen field has no
// value (e.g. serial number on an asset with none) so the UI can explain it.
const codeText = ref('')

const style = ref('card')
const codetype = ref('qr')
const encodes = ref('assetpage')
// Output target: 'single' standalone label, or 'uline-sheet' placing this one
// label at sheetCell (1-6) of a ULINE 6-up sheet.
const outputMode = ref('single')
const sheetCell = ref(1)

const hasLocation = computed(() => hasLocationType(assettype))

const extension = computed(() => (asset.value && config) ? asset.value[config.extkey] : null)

const cardTitle = computed(() => {
  if (!asset.value) return ''
  const ext = extension.value || {}
  return ext.modelname
    || ext.measuringtooltypename
    || asset.value.assettypename
    || (config ? config.label : 'Asset')
})

const imageUrl = computed(() => {
  const ext = extension.value
  return (ext && ext.imageurl) ? withBase(ext.imageurl) : null
})

// Small identity table shown on the card.
const identityFields = computed(() => {
  if (!asset.value) return []
  const rows = []
  if (asset.value.assetnumber) rows.push({ label: 'Asset #', value: asset.value.assetnumber })
  if (asset.value.serialnumber) rows.push({ label: 'Serial', value: asset.value.serialnumber })
  if (asset.value.name) rows.push({ label: 'Name', value: asset.value.name })
  if (asset.value.locationname) rows.push({ label: 'Location', value: asset.value.locationname })
  return rows
})

// Human caption printed under the code.
const caption = computed(() => captionFor(asset.value, encodes.value))

// Human phrase for the current encode mode, used in the "nothing to encode"
// message.
const ENCODE_LABELS = {
  assetnumber: 'asset number', serialnumber: 'serial number',
  location: 'inspection location', assetpage: 'page link', custom: 'target',
}
const encodeLabel = computed(() =>
  ENCODE_LABELS[effEncodes(encodes.value, asset.value)] || 'value')

async function renderCode() {
  const text = await resolveText(assettype, asset.value, encodes.value)
  codeText.value = text
  if (!text) { qrImage.value = ''; return }
  if (codetype.value === 'qr') {
    qrImage.value = await renderQrDataUrl(text)
  } else {
    await nextTick()
    if (!barcodeEl.value) return
    try {
      barcodeInto(barcodeEl.value, text, { height: 70 })
    } catch (err) {
      console.error('Barcode error:', err)
    }
  }
}

onMounted(async () => {
  if (!config) { loading.value = false; return }
  style.value = (await getSetting('label_default_style', 'card')) === 'plain' ? 'plain' : 'card'
  codetype.value = (await getSetting('label_default_codetype', 'qr')) === 'barcode' ? 'barcode' : 'qr'
  encodes.value = await resolveDefaultEncodes(assettype)
  try {
    const response = await config.api.get(route.params.id)
    asset.value = response.data.data
  } catch (err) {
    console.error('Error loading asset:', err)
  } finally {
    loading.value = false
    await nextTick()
    renderCode()
  }
})

// outputMode/sheetCell re-mount the live label element, so redraw the barcode
// into the newly rendered svg (the qr path is just an <img> src, unaffected).
watch([style, codetype, encodes, outputMode, sheetCell], renderCode)

function print() {
  window.print()
}
</script>

<style scoped>
/* Standalone label is a small stock; the ULINE sheet is a letter page. Named */
/* pages let each render its own size (only one branch renders at a time). */
@page { size: 2.13in 3.38in; margin: 0; }
@page uline { size: letter; margin: 0; }
.print-sheet { page: uline; }

.no-print { padding: 20px; }
.controls {
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
  max-width: 40rem;
}
.controls h3 { margin-top: 0; }
.control-row { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 12px; }
.control-row label { display: flex; flex-direction: column; font-size: 0.875rem; gap: 4px; }
.control-row select { padding: 6px; font-size: 0.875rem; }
.control-note { color: var(--warning); font-size: 0.8125rem; margin: 0 0 12px; }

/* Cell picker: 2x3 grid mirroring the physical ULINE cell positions. */
.cell-picker { margin-bottom: 12px; }
.cell-picker-label { display: block; font-size: 0.875rem; margin-bottom: 4px; }
.cell-grid {
  display: grid;
  grid-template-columns: repeat(2, 3rem);
  grid-auto-rows: 3rem;
  gap: 6px;
}
.cell-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  cursor: pointer;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
}
.cell-btn:hover { border-color: var(--primary); }
.cell-btn.active {
  background: var(--primary);
  color: white;
  border-color: var(--primary);
}

.print-btn {
  padding: 10px 30px;
  font-size: 16px;
  cursor: pointer;
  background: var(--primary);
  color: white;
  border: none;
  border-radius: 5px;
}
.print-btn:hover { background: var(--primary-dark); }

.loading-msg, .error-msg { padding: 1rem 0; color: var(--text-light); }

.label-sheet { display: flex; justify-content: center; padding: 20px 0; }

.asset-label {
  width: 2.13in;
  min-height: 3.38in;
  background: white;
  color: #000;
  border: 1px solid #ccc;
  box-sizing: border-box;
  padding: 0.15in;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.asset-label.plain { justify-content: center; min-height: 2in; }

.label-title {
  font-size: 12pt;
  font-weight: bold;
  text-align: center;
  margin-bottom: 0.08in;
}
.label-image {
  max-width: 1.6in;
  max-height: 1.2in;
  object-fit: contain;
  margin-bottom: 0.08in;
}
.label-fields { width: 100%; margin-bottom: 0.08in; }
.label-field {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  font-size: 8pt;
  line-height: 1.4;
}
.field-label { color: #555; }
.field-value { font-weight: bold; text-align: right; word-break: break-all; }

.code-area {
  margin-top: auto;
  text-align: center;
  width: 100%;
}
.code-qr { width: 1.5in; height: 1.5in; }
.code-barcode { width: 1.8in; height: 0.9in; }
.code-caption {
  font-size: 12pt;
  font-weight: bold;
  font-family: monospace;
  margin-top: 0.02in;
}
.code-missing {
  font-size: 9pt;
  color: #999;
  padding: 0.3in 0.1in;
}

/* ULINE 6-up sheet (replicated from AssetLabelBatch; batch left untouched). */
.sheets-container { display: flex; justify-content: center; padding: 20px 0; }
.print-sheet {
  width: 8.5in;
  height: 11in;
  background: white;
  position: relative;
  border: 1px solid #ccc;
}
.sheet-label { position: absolute; top: -25px; left: 0; font-size: 12px; color: #666; }
.label {
  width: 3in;
  height: 3in;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.1in;
  box-sizing: border-box;
}
.label.inactive { border: 1px dashed #ccc; }
.label.active { border: 2px solid var(--primary); }

/* ULINE S-5627 / 6-up 3in cell positions on a letter sheet (match batch). */
.pos-1 { top: 0.875in; left: 1.1875in; }
.pos-2 { top: 0.875in; left: 4.3125in; }
.pos-3 { top: 4in; left: 1.1875in; }
.pos-4 { top: 4in; left: 4.3125in; }
.pos-5 { top: 7.125in; left: 1.1875in; }
.pos-6 { top: 7.125in; left: 4.3125in; }

/* The label shrunk to fit a 3in cell (standalone stock is taller than 3in). */
.label .asset-label.in-cell {
  width: auto;
  min-height: 0;
  border: none;
  padding: 0;
  justify-content: center;
}
.label .asset-label.in-cell .label-title { font-size: 10pt; margin-bottom: 0.04in; }
.label .asset-label.in-cell .label-image { max-width: 1.2in; max-height: 0.7in; margin-bottom: 0.04in; }
.label .asset-label.in-cell .label-fields { margin-bottom: 0.04in; }
.label .asset-label.in-cell .code-area { margin-top: 0.05in; }
.label .asset-label.in-cell .code-qr { width: 1.1in; height: 1.1in; }
.label .asset-label.in-cell .code-barcode { width: 2.2in; height: 0.7in; }
.label .asset-label.in-cell .code-caption { font-size: 10pt; }

@media print {
  .no-print { display: none !important; }
  .label-sheet { padding: 0; }
  .asset-label { border: none; }
  .sheets-container { padding: 0; }
  .print-sheet { border: none; }
  .label { border: none !important; }
  .label.inactive { visibility: hidden; }
  body, .asset-label, .code-qr, .code-barcode {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
}
</style>
