import { defineSisHandler } from "../../../../utils/listings/routeHelper"
import { findListingByKey, findListingBySku, insertListing, queueChange } from "../../../../utils/listings/listingStore"
import { getListingAdapter, supportsListings } from "../../../../utils/listings/adapters"
import { resolveOrderSourceCurrencyId } from "../../../../utils/listings/importer"
import { flushNowIfImmediate } from "../../../../utils/listings/immediate"

// POST /api/sales/sms/listings/create
//   { orderSourceId, items: [{ productId, asin?, price, qty, minPrice?, maxPrice? }] }
// "List products": creates a pending listing per product and queues a `create`
// change. Amazon: offer-only PUT against the ASIN (ListingKey = SKU). Shopify: a new
// product + variant is created by the adapter, which then replaces the provisional
// ListingKey (= SKU) with the variant GID and fills product / inventory ids.
export default defineSisHandler(async ({ event, f, userLabel }) => {
  const body = await readBody(event).catch(() => ({}))
  const orderSourceId = Number(body?.orderSourceId)
  const items: any[] = Array.isArray(body?.items) ? body.items : []
  if (!orderSourceId) return { status: 400, message: 'orderSourceId is required' }
  if (!items.length) return { status: 400, message: 'items[] is empty' }
  if (items.length > 200) return { status: 400, message: 'at most 200 items per call' }
  const orderSource: any = await f(`models/c_ordersource/${orderSourceId}`)
  if (!orderSource?.id) return { status: 404, message: 'Order source not found' }
  const adapter = getListingAdapter(orderSource)
  if (!adapter || !supportsListings(orderSource)) return { status: 400, message: 'This order source has no listings adapter' }
  const orgId = Number(orderSource?.AD_Org_ID?.id) || 0
  const cur = await resolveOrderSourceCurrencyId(f, orderSource, 'EUR')
  const ctx: any = { orderSource, orderSourceId, orgId, marketplace: adapter.key, fetch: f, log: () => {} }

  const created: any[] = []; const errors: { productId: number; error: string }[] = []
  for (const it of items) {
    const productId = Number(it?.productId)
    try {
      if (!productId) throw new Error('productId missing')
      const product: any = await f(`models/m_product/${productId}`)
      if (!product?.id) throw new Error('product not found')
      const value = String(product.Value || '').trim()
      const isAmazon = adapter.key === 'amazon'
      let asin = isAmazon ? (String(it?.asin || product.asin || '').trim().toUpperCase() || null) : null
      const price = Number(String(it?.price ?? '').replace(',', '.'))
      const qty = it?.qty != null && it?.qty !== '' ? Math.trunc(Number(it.qty)) : 0
      if (!Number.isFinite(price) || price <= 0) throw new Error('price must be a positive number')
      if (!Number.isFinite(qty) || qty < 0) throw new Error('qty must be >= 0')
      const why = adapter.validateCreate?.(ctx, { value, asin })
      if (why) throw new Error(why)
      if (await findListingByKey(f, orderSourceId, value)) throw new Error(`already listed (key ${value})`)
      if (!isAmazon && await findListingBySku(f, orderSourceId, value)) throw new Error(`already listed (SKU ${value})`)
      if (asin && !product.asin) await f(`models/m_product/${productId}`, 'PUT', { asin })
      const minPrice = it?.minPrice != null && it?.minPrice !== '' ? Number(String(it.minPrice).replace(',', '.')) : null
      const maxPrice = it?.maxPrice != null && it?.maxPrice !== '' ? Number(String(it.maxPrice).replace(',', '.')) : null
      const listing = await insertListing(f, {
        orgId, orderSourceId, sellerSku: value, listingKey: value, name: product.Name || value,
        productId, externalProductId: asin, listingStatus: 'pending', fulfillmentChannel: 'DEFAULT',
        price: Math.round(price * 100) / 100, qty, minPrice, maxPrice, currencyId: cur.id, isPriceTaxIncluded: true,
        syncStatus: 'queued', meta: { createdFrom: 'erp', by: userLabel, marketplace: adapter.key }
      })
      const change = await queueChange(f, listing, { changeType: 'create', newValue: String(price), description: userLabel })
      created.push({ listingId: listing.id, productId, sku: value, asin, changeId: change.id })
    } catch (e: any) {
      errors.push({ productId, error: String(e?.data?.detail || e?.message || e).slice(0, 300) })
    }
  }
  const delivered = created.length ? await flushNowIfImmediate(f, orderSource) : null
  console.log('[sis] list products', { user: userLabel, orderSourceId, created: created.length, errors: errors.length, immediate: !!delivered })
  return { status: 200, created, errors, delivered: delivered ? { sent: delivered.sources?.[0]?.sent || 0, errors: delivered.sources?.[0]?.errors || 0 } : null }
})
