// Shared wiring for the asset label pages (single AssetLabel.vue and batch
// AssetLabelBatch.vue): per-type api/route config plus the "what does the code
// encode" resolution so both surfaces behave identically.
import {
  machinesApi, computersApi, printersApi, networkApi, measuringtoolsApi,
} from '../../api'
import { fillUrlTemplate } from '@/utils/qrTarget'
import { getSetting, getSiteBaseUrl } from '@/utils/siteSettings'

// Per asset-type: which api loads it, its detail/list routes, the extension key
// nested in the merged payload, and its qr_target_<type> settings key.
export const TYPE_CONFIG = {
  machine: {
    api: machinesApi, extkey: 'machine', targetKey: 'qr_target_machine',
    label: 'Machine', detailPath: id => `/machines/${id}`, listPath: '/machines',
  },
  computer: {
    api: computersApi, extkey: 'computer', targetKey: 'qr_target_computer',
    label: 'Computer', detailPath: id => `/pcs/${id}`, listPath: '/pcs',
  },
  printer: {
    api: printersApi, extkey: 'printer', targetKey: 'qr_target_printer',
    label: 'Printer', detailPath: id => `/printers/${id}`, listPath: '/printers',
  },
  network_device: {
    api: networkApi, extkey: 'network_device', targetKey: 'qr_target_network_device',
    label: 'Network Device', detailPath: id => `/network/${id}`, listPath: '/network',
  },
  measuring_tool: {
    api: measuringtoolsApi, extkey: 'measuringtool', targetKey: 'qr_target_measuring_tool',
    label: 'Measuring Tool', detailPath: id => `/measuringtools/${id}`, listPath: '/measuringtools',
  },
}

// Hardcoded fallback default per type when the site setting is unset. Machines
// encode their machine number, measuring tools their inspection location.
const DEFAULT_ENCODES = { machine: 'assetnumber', measuring_tool: 'location' }

export function hasLocationType(assettype) {
  return assettype === 'measuring_tool'
}

// The default encode mode for a type: the label_default_encodes_<type> site
// setting when valid, else the hardcoded fallback.
export async function resolveDefaultEncodes(assettype) {
  const valid = ['assetpage', 'assetnumber', 'serialnumber', 'custom']
  if (hasLocationType(assettype)) valid.push('location')
  const seeded = await getSetting(`label_default_encodes_${assettype}`, '')
  return valid.includes(seeded) ? seeded : (DEFAULT_ENCODES[assettype] || 'assetpage')
}

// 'location' degrades to the asset page when the asset has no location code.
export function effectiveEncodes(encodes, asset) {
  if (encodes === 'location' && !asset?.locationcode) return 'assetpage'
  return encodes
}

function tokensFor(asset) {
  return {
    assetid: asset.assetid || '',
    assetnumber: asset.assetnumber || '',
    serialnumber: asset.serialnumber || '',
    name: asset.name || '',
    pluginid: asset.pluginid || '',
    locationcode: asset.locationcode || '',
    locationname: asset.locationname || '',
  }
}

// The string a label's code encodes for one asset. Empty when the chosen field
// has no value (e.g. serial number on an asset with none).
export async function resolveCodeText(assettype, asset, encodes) {
  const config = TYPE_CONFIG[assettype]
  if (!config || !asset) return ''
  const detailId = asset.pluginid
  const assetPageUrl = `${await getSiteBaseUrl()}${config.detailPath(detailId)}`
  switch (effectiveEncodes(encodes, asset)) {
    case 'assetnumber': return asset.assetnumber || ''
    case 'serialnumber': return asset.serialnumber || ''
    case 'location': return asset.locationcode || ''
    case 'custom': {
      const template = (await getSetting(config.targetKey, '')).trim()
      return template ? fillUrlTemplate(template, tokensFor(asset)) : assetPageUrl
    }
    case 'assetpage':
    default: return assetPageUrl
  }
}

// Human caption printed under the code.
export function captionFor(asset, encodes) {
  if (!asset) return ''
  switch (effectiveEncodes(encodes, asset)) {
    case 'location': return asset.locationcode || ''
    case 'serialnumber': return asset.serialnumber || ''
    case 'assetnumber':
    default: return asset.assetnumber || ''
  }
}
