import type { visibilityFacts } from '@znet/catalog-db'

type Facts = Awaited<ReturnType<typeof visibilityFacts>>

export type CheckStatus = 'pass' | 'fail' | 'warn' | 'info'
export interface VisibilityCheck {
  check: string
  status: CheckStatus
  detail: string
}

/**
 * Explain why a product may not be visible on a store view's storefront, in the order a
 * merchandiser would check. Pure function over catalog facts so it is easy to test and extend.
 * Live salable quantity is added by the MCP server, which can reach Magento.
 */
export function diagnoseVisibility({ product: p, store, variantStates }: Facts, opts: { stock: boolean } = { stock: true }) {
  const checks: VisibilityCheck[] = []
  const add = (check: string, status: CheckStatus, detail: string) => checks.push({ check, status, detail })

  if (p.deleted) add('exists', 'fail', 'Product no longer exists in Magento (removed at last reconciliation).')

  add('status', p.status === 'Enabled' ? 'pass' : 'fail', `Status is ${p.status ?? 'unknown'} for store view "${store.code}".`)

  if (store.storeId !== 0) {
    const inWebsite = p.websiteIds.includes(store.websiteId)
    add('website', inWebsite ? 'pass' : 'fail', inWebsite
      ? `Assigned to website ${store.websiteCode ?? store.websiteId}.`
      : `Not assigned to website ${store.websiteCode ?? store.websiteId} (assigned to: ${p.websiteIds.join(', ') || 'none'}).`)
  }

  if (p.visibility === 'Not Visible Individually') {
    if (p.parents.length) {
      add('visibility', 'info', `"Not Visible Individually" — shown only via parent product(s): ${p.parents.map(x => `${x.sku} (${x.kind})`).join(', ')}. Check the parent instead.`)
    } else {
      add('visibility', 'fail', '"Not Visible Individually" and not part of any configurable/bundle/grouped product, so it cannot be reached on the storefront.')
    }
  } else {
    add('visibility', 'pass', `Visibility is "${p.visibility}".`)
  }

  const inCatalog = p.visibility === 'Catalog' || p.visibility === 'Catalog, Search'
  if (inCatalog) {
    if (!p.categories.length) add('categories', 'warn', 'Not assigned to any category — will not appear in category listings (search/URL still work).')
    else if (p.categories.every(c => c.isActive === false)) add('categories', 'fail', 'All assigned categories are disabled for this store view.')
    else add('categories', 'pass', `In ${p.categories.length} categor${p.categories.length === 1 ? 'y' : 'ies'}: ${p.categories.map(c => c.name ?? c.categoryId).join(', ')}.`)
  }

  if (p.typeId === 'configurable') {
    const enabled = variantStates.filter(v => v.status === 1)
    const sellable = enabled.filter(v => v.in_stock)
    if (!p.variants.length) add('variants', 'fail', 'Configurable product has no variants linked.')
    else if (!enabled.length) add('variants', 'fail', `All ${p.variants.length} variants are disabled.`)
    else if (!opts.stock) add('variants', 'pass', `${enabled.length} of ${p.variants.length} variants enabled.`)
    else if (!sellable.length) add('variants', 'fail', `${enabled.length} enabled variants but none in stock — hidden if "Display Out of Stock Products" is off.`)
    else add('variants', 'pass', `${sellable.length} of ${p.variants.length} variants enabled and in stock.`)
  } else if (!opts.stock) {
    // Stock is not managed in Magento for this store — nothing to check.
  } else if (p.inventory.inStock === false) {
    add('stock', 'warn', `Out of stock (qty ${p.inventory.totalQty}). Hidden from listings if "Display Out of Stock Products" is off.`)
  } else if (p.inventory.inStock) {
    add('stock', 'pass', `In stock (qty ${p.inventory.totalQty} across ${p.inventory.sources.length} source(s)).`)
  } else {
    add('stock', 'info', 'No stock record synced for this SKU.')
  }

  if (['simple', 'virtual', 'downloadable'].includes(p.typeId) && !(p.pricing.effectivePrice && p.pricing.effectivePrice > 0)) {
    add('price', 'fail', 'No price (or zero price) — Magento hides unpriced simple products from listings.')
  }

  if (!p.urlKey) add('url_key', 'warn', 'No URL key — product page URL cannot be generated.')

  const failed = checks.filter(c => c.status === 'fail')
  return {
    sku: p.sku,
    store: store.code,
    likelyVisible: failed.length === 0,
    summary: failed.length
      ? `Likely NOT visible: ${failed.map(f => f.check).join(', ')}.`
      : 'No blocking catalog issue found. If it is still not visible, check indexers (catalog_product_price, catalogsearch_fulltext, inventory), full-page cache, and shared catalog / category permissions (B2B).',
    checks,
    asOf: p.syncedAt,
  }
}
