// Штрихкод-утилиты: генерация валидных кодов под разные форматы.
//
// Внутренние EAN-13 магазина начинаются с "2" — зарезервированный префикс
// для in-store use, не пересекается с GTIN реальных товаров.

import { BarcodeType } from '@/lib/types'

function digitsChecksum(first: string, weightAtOdd: number): number {
  // Общая EAN/UPC-подобная формула: сумма с чередующимися весами, остаток от 10.
  // Нечётные позиции (с индекса 0) — weightAtOdd, чётные — 1.
  let sum = 0
  for (let i = 0; i < first.length; i++) {
    const d = first.charCodeAt(i) - 48
    sum += i % 2 === 0 ? d * weightAtOdd : d
  }
  return (10 - (sum % 10)) % 10
}

function randomDigits(n: number): string {
  let s = ''
  for (let i = 0; i < n; i++) s += Math.floor(Math.random() * 10).toString()
  return s
}

function randomAlnum(n: number): string {
  const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  let s = ''
  for (let i = 0; i < n; i++) s += alphabet[Math.floor(Math.random() * alphabet.length)]
  return s
}

function ean13(): string {
  const body = '2' + randomDigits(11)
  return body + digitsChecksum(body, 3).toString()
}

function ean8(): string {
  // EAN-8: 7 цифр + checksum. Веса: нечётные×3, чётные×1 (с индекса 0).
  const body = randomDigits(7)
  return body + digitsChecksum(body, 3).toString()
}

function upca(): string {
  // UPC-A: 11 цифр + checksum. Та же формула что у EAN-13.
  const body = randomDigits(11)
  return body + digitsChecksum(body, 3).toString()
}

function upce(): string {
  // Упрощённая генерация: 8 случайных цифр (реальный UPC-E строится через
  // сжатие UPC-A по спецправилам; для внутренних нужд достаточно числовой
  // последовательности нужной длины).
  return randomDigits(8)
}

/** Сгенерировать внутренний EAN-13 с префиксом "2" и случайной серединой. */
export function generateEan13InternalPrefix2(): string {
  return ean13()
}

/** Сгенерировать числовой артикул для товара. На бэкенде есть надёжный
 * max(article)+1 генератор, но для UX удобно сразу подставить значение в поле:
 * берём последние 6 цифр времени + 3 случайных. Уникальность подтверждает
 * сервер; конфликт по unique index возвращается как 400 «Артикул уже занят». */
export function generateArticle(): string {
  const ts = Date.now().toString().slice(-6)
  const rnd = Math.floor(100 + Math.random() * 900).toString()
  return ts + rnd
}

/** Сгенерировать штрихкод под указанный формат. */
export function generateBarcode(type: BarcodeType): string {
  switch (type) {
    case BarcodeType.Ean13: return ean13()
    case BarcodeType.Ean8: return ean8()
    case BarcodeType.Upca: return upca()
    case BarcodeType.Upce: return upce()
    case BarcodeType.Code128:
    case BarcodeType.Code39: return randomAlnum(12)
    case BarcodeType.Other:
    default: return ean13()
  }
}
