#!/usr/bin/env bun
import { existsSync, readFileSync, writeFileSync } from 'fs'
import { join } from 'path'

const root = process.cwd()
const outRoot = join(root, 'content_population_exports')
const contentRoot = join(root, 'data', 'content')
const intelRoot = join(root, 'data', 'intelligence')
const catalogPath = join(root, 'data', 'pipeline', 'catalog.json')

const requiredViews = [
  { view: 'review-aspects', source: 'Feefo raw reviews', gate: 'first_party' },
  { view: 'strengths-weaknesses', source: 'Feefo raw reviews', gate: 'first_party' },
  { view: 'conversion-blockers', source: 'Feefo raw reviews', gate: 'first_party' },
  { view: 'improvements', source: 'Feefo raw reviews', gate: 'first_party' },
  { view: 'image-audit', source: 'PDP/image crawl + Feefo blockers', gate: 'image' },
  { view: 'photo-brief', source: 'Image audit + product content', gate: 'image' },
  { view: 'competitor-comparison', source: 'Competitor PDP + Amazon/Trustpilot', gate: 'external_sources' },
  { view: 'amazon-reviews', source: 'Amazon source drops', gate: 'amazon' },
  { view: 'reddit-pulse', source: 'Reddit/social source drops', gate: 'reddit' },
  { view: 'flavor-intelligence', source: 'Competitor PDP + Amazon/Reddit', gate: 'npd' },
  { view: 'audience-profile', source: 'Feefo + Amazon + Reddit', gate: 'audience' },
  { view: 'claims-evidence', source: 'Clinical claims library', gate: 'claims' }
]
function readJson(path: string, fallback: any = null) {
  if (!existsSync(path)) return fallback
  return JSON.parse(readFileSync(path, 'utf8').replace(/^\uFEFF/, ''))
}
function csv(rows: any[], headers: string[]) {
  const esc = (value: any) => {
    if (Array.isArray(value)) value = value.join(' | ')
    if (value === undefined || value === null) value = ''
    value = String(value)
    return /[",\n\r]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value
  }
  return [headers.join(','), ...rows.map(row => headers.map(header => esc(row[header])).join(','))].join('\n') + '\n'
}
function priority(totalReviews: number) {
  if (totalReviews >= 500) return 'P0'
  if (totalReviews >= 250) return 'P1'
  if (totalReviews >= 100) return 'P2'
  return 'P3'
}
const catalogBySku = Object.fromEntries(readJson(catalogPath, []).map((product: any) => [product.sku, product]))
const productFiles = (await Array.fromAsync(new Bun.Glob('*.json').scan({ cwd: join(contentRoot, 'products') })))
  .sort()
  .map(file => readJson(join(contentRoot, 'products', file)))
const rows: any[] = []
for (const product of productFiles) {
  const catalog = catalogBySku[product.sku] || {}
  const missingViews = []
  for (const spec of requiredViews) {
    const exists = existsSync(join(intelRoot, product.sku, `${spec.view}.json`))
    if (!exists) {
      rows.push({
        Priority: priority(Number(catalog.total_reviews || 0)),
        SKU: product.sku,
        Product: product.name || catalog.name || '',
        TotalReviews: catalog.total_reviews || 0,
        View: spec.view,
        RequiredSource: spec.source,
        Gate: spec.gate,
        TargetPath: `data/intelligence/${product.sku}/${spec.view}.json`,
        Status: 'missing'
      })
      missingViews.push(spec.view)
    }
  }
}
rows.sort((a, b) => a.Priority.localeCompare(b.Priority) || Number(b.TotalReviews) - Number(a.TotalReviews) || a.SKU.localeCompare(b.SKU) || a.View.localeCompare(b.View))
const bySku = new Map<string, any>()
for (const row of rows) {
  const entry = bySku.get(row.SKU) || { SKU: row.SKU, Product: row.Product, TotalReviews: row.TotalReviews, Priority: row.Priority, MissingViews: [], MissingCount: 0 }
  entry.MissingViews.push(row.View)
  entry.MissingCount += 1
  bySku.set(row.SKU, entry)
}
const skuRows = [...bySku.values()].map(row => ({ ...row, MissingViews: row.MissingViews.join(' | ') })).sort((a, b) => a.Priority.localeCompare(b.Priority) || Number(b.TotalReviews) - Number(a.TotalReviews) || a.SKU.localeCompare(b.SKU))
const gateSummary = requiredViews.map(spec => ({
  View: spec.view,
  Gate: spec.gate,
  RequiredSource: spec.source,
  Missing: rows.filter(row => row.View === spec.view).length,
  Present: productFiles.length - rows.filter(row => row.View === spec.view).length,
  Total: productFiles.length
}))
writeFileSync(join(outRoot, 'intelligence_generation_workqueue.csv'), csv(rows, ['Priority', 'SKU', 'Product', 'TotalReviews', 'View', 'RequiredSource', 'Gate', 'TargetPath', 'Status']), 'utf8')
writeFileSync(join(outRoot, 'intelligence_generation_by_sku.csv'), csv(skuRows, ['Priority', 'SKU', 'Product', 'TotalReviews', 'MissingCount', 'MissingViews']), 'utf8')
writeFileSync(join(outRoot, 'intelligence_generation_summary.csv'), csv(gateSummary, ['View', 'Gate', 'RequiredSource', 'Present', 'Missing', 'Total']), 'utf8')
const manifest = { generatedAt: new Date().toISOString(), ready: rows.length === 0, totalProducts: productFiles.length, missingTasks: rows.length, affectedSkus: skuRows.length, gateSummary, topSkus: skuRows.slice(0, 25) }
writeFileSync(join(outRoot, 'intelligence_generation_workqueue.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8')
console.log(`Intelligence workqueue ready: ${manifest.ready}`)
console.log(`Missing tasks: ${manifest.missingTasks}`)
console.log(`Affected SKUs: ${manifest.affectedSkus}`)
if (!manifest.ready) process.exitCode = 1
