export type SecondaryFormat = 'DXF' | 'SVG' | 'OBJ' | 'PLY' | 'STL' | 'PDF' | 'IFC' | 'CSV'
export type SecondaryFormatDescriptor = { format: SecondaryFormat; category: '2d' | 'mesh' | 'bim' | 'data'; mime: string; importMode: 'native' | 'proxy'; exportMode: 'native' | 'proxy'; deterministic: boolean; maxBytes: number }
export type SecondaryRecord = { id: string; format: SecondaryFormat; byteLength: number; detected: boolean; proxy: boolean; hash: string }
export type SecondaryFormatsSnapshot = { descriptors: SecondaryFormatDescriptor[]; records: SecondaryRecord[]; version: number }
export type SecondaryFormatsApi = { descriptors(): SecondaryFormatDescriptor[]; detect(format: SecondaryFormat, bytes: Uint8Array): boolean; importBytes(input: { id: string; format: SecondaryFormat; bytes: Uint8Array }): SecondaryRecord; exportBytes(format: SecondaryFormat, input?: { label?: string; width?: number; height?: number }): Uint8Array; exportRecord(id: string): Uint8Array; snapshot(): SecondaryFormatsSnapshot; remove(id: string): void }

const descriptors: SecondaryFormatDescriptor[] = [
  { format: 'DXF', category: '2d', mime: 'image/vnd.dxf', importMode: 'proxy', exportMode: 'proxy', deterministic: true, maxBytes: 16 * 1024 * 1024 },
  { format: 'SVG', category: '2d', mime: 'image/svg+xml', importMode: 'proxy', exportMode: 'native', deterministic: true, maxBytes: 8 * 1024 * 1024 },
  { format: 'OBJ', category: 'mesh', mime: 'model/obj', importMode: 'proxy', exportMode: 'native', deterministic: true, maxBytes: 32 * 1024 * 1024 },
  { format: 'PLY', category: 'mesh', mime: 'model/ply', importMode: 'proxy', exportMode: 'proxy', deterministic: true, maxBytes: 32 * 1024 * 1024 },
  { format: 'STL', category: 'mesh', mime: 'model/stl', importMode: 'proxy', exportMode: 'native', deterministic: true, maxBytes: 32 * 1024 * 1024 },
  { format: 'PDF', category: '2d', mime: 'application/pdf', importMode: 'proxy', exportMode: 'proxy', deterministic: true, maxBytes: 16 * 1024 * 1024 },
  { format: 'IFC', category: 'bim', mime: 'application/x-step', importMode: 'proxy', exportMode: 'proxy', deterministic: true, maxBytes: 64 * 1024 * 1024 },
  { format: 'CSV', category: 'data', mime: 'text/csv', importMode: 'proxy', exportMode: 'proxy', deterministic: true, maxBytes: 16 * 1024 * 1024 },
]

const clone = <T>(value: T): T => JSON.parse(JSON.stringify(value)) as T
const descriptor = (format: SecondaryFormat) => descriptors.find((entry) => entry.format === format)!
const hash = (bytes: Uint8Array) => { let value = 2166136261; for (const byte of bytes) value = Math.imul(value ^ byte, 16777619); return (value >>> 0).toString(16).padStart(8, '0') }
const text = (bytes: Uint8Array) => new TextDecoder().decode(bytes.slice(0, Math.min(bytes.byteLength, 4096))).trimStart()
const detects = (format: SecondaryFormat, bytes: Uint8Array) => {
  const prefix = text(bytes)
  if (format === 'DXF') return /(^|\n)0\s*\nSECTION/.test(prefix)
  if (format === 'SVG') return /^<svg(?:\s|>)/i.test(prefix)
  if (format === 'OBJ') return /(^|\n)v\s+[-+0-9.]/.test(prefix)
  if (format === 'PLY') return /^ply\s/.test(prefix)
  if (format === 'STL') return /^solid(?:\s|\n)/i.test(prefix) || bytes.byteLength >= 84
  if (format === 'PDF') return /^%PDF-/.test(prefix)
  if (format === 'IFC') return /^ISO-10303-21;/.test(prefix) && /FILE_SCHEMA\s*\(\s*\(\s*'IFC/i.test(prefix)
  return /^Label,Width,Height(?:\r?\n)[^,\r\n]+,[^,\r\n]+,[^,\r\n]+(?:\r?\n|$)/.test(prefix)
}

export const createSecondaryFormats = (): SecondaryFormatsApi => {
  const records = new Map<string, SecondaryRecord>()
  const payloads = new Map<string, Uint8Array>()
  let version = 0
  return {
    descriptors: () => clone(descriptors),
    detect: (format, bytes) => {
      if (!(bytes instanceof Uint8Array)) throw new TypeError('Secondary format bytes must be Uint8Array.')
      return detects(format, bytes)
    },
    importBytes: ({ id, format, bytes }) => {
      const selected = descriptor(format)
      if (!id.trim() || records.has(id)) throw new RangeError(`Secondary format record already exists: ${id}`)
      if (bytes.byteLength <= 0 || bytes.byteLength > selected.maxBytes) throw new RangeError(`${format} payload exceeds the supported limit.`)
      const detected = detects(format, bytes)
      if (!detected) throw new RangeError(`${format} payload signature was not recognized.`)
      const record: SecondaryRecord = { id, format, byteLength: bytes.byteLength, detected, proxy: selected.importMode === 'proxy', hash: hash(bytes) }
      records.set(id, record)
      payloads.set(id, Uint8Array.from(bytes))
      version += 1
      return clone(record)
    },
    exportBytes: (format, input = {}) => {
      const rawLabel = input.label ?? 'BitBybit CAD'
      const label = rawLabel.replace(/[<>\r\n,']/g, ' ').trim() || 'BitBybit CAD'
      const width = Number.isFinite(input.width) ? input.width! : 100
      const height = Number.isFinite(input.height) ? input.height! : 80
      if (width <= 0 || height <= 0) throw new RangeError('Secondary export dimensions must be positive.')
      const output = format === 'SVG' ? `<svg xmlns="http://www.w3.org/2000/svg" width="${width}mm" height="${height}mm" role="img" aria-label="${label}"><title>${label}</title><rect width="100%" height="100%" fill="none" stroke="#222"/></svg>\n`
        : format === 'OBJ' ? `# ${label}\nv 0 0 0\nv ${width} 0 0\nv ${width} ${height} 0\nv 0 ${height} 0\nf 1 2 3 4\n`
          : format === 'STL' ? `solid ${label}\nendsolid ${label}\n`
            : format === 'PLY' ? 'ply\nformat ascii 1.0\nelement vertex 0\nend_header\n'
              : format === 'DXF' ? '0\nSECTION\n2\nENTITIES\n0\nENDSEC\n0\nEOF\n'
                : format === 'PDF' ? `%PDF-1.4\n% BitBybit ${label}\n%%EOF\n`
                  : format === 'IFC' ? `ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION(('${label}'),'2;1');\nFILE_SCHEMA(('IFC4'));\nENDSEC;\nDATA;\nENDSEC;\nEND-ISO-10303-21;\n`
                    : `Label,Width,Height\n${label},${width},${height}\n`
      return new TextEncoder().encode(output)
    },
    exportRecord: (id) => {
      const bytes = payloads.get(id)
      if (!bytes) throw new RangeError(`Secondary format record does not exist: ${id}`)
      return Uint8Array.from(bytes)
    },
    snapshot: () => ({ descriptors: clone(descriptors), records: [...records.values()].map(clone), version }),
    remove: (id) => {
      if (!records.delete(id)) throw new RangeError(`Secondary format record does not exist: ${id}`)
      payloads.delete(id)
      version += 1
    },
  }
}
