// Export the shop-floor map (current filtered assets on the facility blueprint)
// to a PDF, entirely client-side. The blueprint image is drawn full-size and
// each visible marker is placed at its scaled coordinate, so the PDF is a crisp
// vector-over-raster page rather than a screen capture.
import { jsPDF } from 'jspdf'
import {
  resolveMarkerColor, getSubtypeId, getAssetTypeColor, markerRingColor,
  UNSPECIFIED_COLOR
} from './mapColors'

function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    img.onload = () => resolve(img)
    img.onerror = () => reject(new Error('Failed to load blueprint image: ' + url))
    img.src = url
  })
}

function hexToRgb(hex) {
  const h = (hex || UNSPECIFIED_COLOR).replace('#', '')
  const v = h.length === 3 ? h.split('').map(c => c + c).join('') : h
  return [parseInt(v.slice(0, 2), 16), parseInt(v.slice(2, 4), 16), parseInt(v.slice(4, 6), 16)]
}

// Build the legend entries (color + label) for the assets present, matching the
// active coloring mode.
function buildLegend(assets, { selectedType, subtypeColors, subtypeNames }) {
  const seen = new Map()
  for (const a of assets) {
    let key, label, color
    if (selectedType) {
      const id = getSubtypeId(a)
      key = id != null ? String(id) : 'none'
      label = (id != null && subtypeNames[id]) || 'Unspecified'
      color = (id != null && subtypeColors[id]) || UNSPECIFIED_COLOR
    } else {
      key = (a.assettype || 'unknown').toLowerCase()
      label = a.assettype || 'Unknown'
      color = getAssetTypeColor(a.assettype)
    }
    if (!seen.has(key)) seen.set(key, { label, color, count: 0 })
    seen.get(key).count += 1
  }
  return [...seen.values()].sort((a, b) => b.count - a.count)
}

export async function exportMapPdf(opts) {
  const {
    assets = [],
    blueprintUrl,
    mapWidth = 3300,
    mapHeight = 2550,
    selectedType = '',
    subtypeColors = {},
    subtypeNames = {},
    filters = [],
    facility = '',
    title = 'Shop Floor Map'
  } = opts

  const img = await loadImage(blueprintUrl)

  const doc = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4', compress: true })
  const pageW = doc.internal.pageSize.getWidth()
  const pageH = doc.internal.pageSize.getHeight()
  const margin = 28

  // ---- Header ----
  doc.setTextColor('#111111')
  doc.setFont('helvetica', 'bold')
  doc.setFontSize(16)
  doc.text(title, margin, margin + 6)

  doc.setFont('helvetica', 'normal')
  doc.setFontSize(9)
  doc.setTextColor('#555555')
  const stamp = new Date().toLocaleString()
  const subParts = [facility, stamp, `${assets.length} asset${assets.length === 1 ? '' : 's'}`].filter(Boolean)
  doc.text(subParts.join('    |    '), margin, margin + 22)

  const filterText = filters.length ? 'Filters: ' + filters.join('    ') : 'Filters: none (all assets)'
  doc.text(filterText, margin, margin + 35)

  // ---- Legend (wraps under the header, pushes the map down) ----
  const legend = buildLegend(assets, { selectedType, subtypeColors, subtypeNames })
  const swatch = 8
  const legendY0 = margin + 50
  const lineH = 15
  let lx = margin
  let ly = legendY0
  doc.setFontSize(8.5)
  for (const entry of legend) {
    const label = `${entry.label} (${entry.count})`
    const w = swatch + 4 + doc.getTextWidth(label) + 16
    if (lx + w > pageW - margin) { lx = margin; ly += lineH }
    const [r, g, b] = hexToRgb(entry.color)
    doc.setFillColor(r, g, b)
    // The page is always white, so the ring is the light-surface one throughout.
    doc.setDrawColor(markerRingColor('light')); doc.setLineWidth(0.3)
    doc.rect(lx, ly - swatch + 1, swatch, swatch, 'FD')
    doc.setTextColor('#333333')
    doc.text(label, lx + swatch + 4, ly)
    lx += w
  }
  const legendBottom = legend.length ? ly + 6 : legendY0

  // ---- Blueprint image, fit into the area below the legend ----
  const aspect = mapWidth / mapHeight
  const contentTop = legendBottom + 8
  const availW = pageW - margin * 2
  const availH = pageH - contentTop - margin
  let imgW = availW
  let imgH = availW / aspect
  if (imgH > availH) { imgH = availH; imgW = availH * aspect }
  const imgX = margin + (availW - imgW) / 2
  const imgY = contentTop + (availH - imgH) / 2

  doc.addImage(img, 'PNG', imgX, imgY, imgW, imgH, undefined, 'FAST')
  doc.setDrawColor('#cccccc'); doc.setLineWidth(0.5)
  doc.rect(imgX, imgY, imgW, imgH)

  // ---- Markers (database Y is top-down, same origin as the drawn image) ----
  const radius = 3.2
  for (const a of assets) {
    if (a.mapx == null || a.mapy == null) continue
    const x = imgX + (a.mapx / mapWidth) * imgW
    const y = imgY + (a.mapy / mapHeight) * imgH
    if (x < imgX || x > imgX + imgW || y < imgY || y > imgY + imgH) continue
    const fill = resolveMarkerColor(a, { selectedType, subtypeColors })
    const [r, g, b] = hexToRgb(fill)
    doc.setFillColor(r, g, b)
    // Prints on white, where a white ring is invisible - use the dark ring.
    doc.setDrawColor(markerRingColor('light')); doc.setLineWidth(0.4)
    doc.circle(x, y, radius, 'FD')
  }

  const dateSlug = new Date().toISOString().slice(0, 10)
  doc.save(`shopfloor-map-${dateSlug}.pdf`)
}
