#!/usr/bin/env bun
import { existsSync } from 'fs'
import { intelPath, listProducts, now, readJson, sourceStatus, writeJson } from './lib/intel-utils'

const catalog = readJson('data/pipeline/catalog.json', [])
const catalogBySku = new Map((Array.isArray(catalog) ? catalog : []).map((row: any) => [row.sku, row]))

function productName(product: any) {
  return product.name || catalogBySku.get(product.sku)?.name || product.sku
}

function reviewVolume(product: any) {
  return Number(catalogBySku.get(product.sku)?.total_reviews || 0)
}

const GENERATOR = 'generate-catalog-intelligence-queues.ts'

function shouldWrite(sku: string, view: string) {
  const path = intelPath(sku, `${view}.json`)
  if (!existsSync(path)) return true
  return readJson(path, {})?.generatedBy === GENERATOR
}

function benefitSeeds(product: any) {
  const fields = product.metafields || {}
  const seeds = [
    ...(Array.isArray(fields.pdpProductBenefits) ? fields.pdpProductBenefits : []),
    fields.pdpBenefits,
    fields.pdpKeyFeatures,
    fields.pdpWhoItsFor,
    fields.pdpKeyIngredients
  ]
    .map((value: any) => String(value || '').trim())
    .filter(Boolean)
  return seeds.length ? seeds.slice(0, 6) : [
    'Verified customer-language extraction still required',
    'Product benefit, format, and dosage clarity need source-backed expansion',
    'Final PDP copy must wait for Feefo/Amazon/Reddit evidence review'
  ]
}

function evidenceStatus() {
  return {
    feefo: 'catalogue_queue_not_quote_level_extracted',
    amazon: sourceStatus('amazon'),
    reddit: sourceStatus('reddit'),
    trustpilot: sourceStatus('trustpilot'),
    note: 'This file closes catalogue coverage as a workqueue/evidence scaffold only. It is not final human-approved copy and must not be treated as source-backed claim evidence.'
  }
}

function scoreFromVolume(totalReviews: number) {
  if (totalReviews >= 500) return 6.5
  if (totalReviews >= 250) return 6
  if (totalReviews >= 100) return 5.5
  if (totalReviews > 0) return 5
  return 4
}

function writeReviewAspects(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'review-aspects')) return false
  const seeds = benefitSeeds(product)
  const total = reviewVolume(product)
  writeJson(intelPath(sku, 'review-aspects.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_seeded_from_product_record',
    evidenceStatus: evidenceStatus(),
    n: total,
    avgRating: null,
    approvalStatus: 'needs_review_language_extraction',
    aspects: seeds.map((seed: string, index: number) => ({
      rank: index + 1,
      reviews: null,
      aspect: seed,
      sentiment: 'needs_review',
      customerJourney: index === 0 ? 'Pre-Purchase' : 'Post-Purchase',
      confidence: 'low',
      exampleQuotes: [],
      extractionTask: 'Extract quote-level Feefo/Amazon/Reddit support before using in final PDP copy.'
    }))
  })
  return true
}

function writeStrengthsWeaknesses(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'strengths-weaknesses')) return false
  const seeds = benefitSeeds(product)
  const total = reviewVolume(product)
  writeJson(intelPath(sku, 'strengths-weaknesses.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_seeded_from_product_record',
    evidenceStatus: evidenceStatus(),
    marketFitScore: {
      value: scoreFromVolume(total),
      confidence: 'low',
      basis: `${total} catalogue review count only; sentiment and quote-level support pending.`,
      n: total
    },
    verdict: 'Queue scaffold only: review-language extraction and human review are required before this can be treated as a final strengths/weaknesses assessment.',
    items: [
      ...seeds.slice(0, 4).map((seed: string, index: number) => ({
        rank: index + 1,
        reviews: null,
        insight: seed,
        sentimentRatio: { positive: null, negative: null },
        classification: index === 0 ? 'Candidate Strength' : 'Needs Evidence',
        detail: 'Seeded from existing product record. Needs verified customer review support before final use.'
      })),
      {
        rank: seeds.slice(0, 4).length + 1,
        reviews: null,
        insight: 'Final weakness analysis pending review extraction',
        sentimentRatio: { positive: null, negative: null },
        classification: 'Evidence Gap',
        detail: 'Do not infer product weaknesses without quote-level review evidence or a visual/PDP audit.'
      }
    ]
  })
  return true
}

function writeConversionBlockers(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'conversion-blockers')) return false
  const fields = product.metafields || {}
  const blockers = [
    {
      blocker: 'Customer-language proof is not extracted yet',
      evidence: 'Catalogue row has review count, but per-theme supporting review quotes are still pending for this SKU.',
      fix: 'Run quote-level Feefo/Amazon/Reddit extraction and map each top theme to supporting reviews.'
    },
    {
      blocker: 'Clinical/compliance mapping may be empty or unapproved',
      evidence: fields.pdpClinicallyShownTo ? 'A clinically_shown_to field exists, but approval still needs checking.' : 'pdpClinicallyShownTo is empty in the product content row.',
      fix: 'Only attach authorised claims from the claims library, then route through human compliance approval.'
    },
    {
      blocker: 'PDP result/how-we-compare assets are assigned but not visually verified',
      evidence: [fields.pdpResults, fields.pdpResultsMobile, fields.pdpHowWeCompare].filter(Boolean).join(' | ') || 'No image filenames assigned.',
      fix: 'Produce/upload the referenced image files and perform visual QA before staging handoff.'
    }
  ]
  writeJson(intelPath(sku, 'conversion-blockers.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_seeded_from_product_record',
    evidenceStatus: evidenceStatus(),
    summary: 'Queue scaffold only: blockers identify what must be proven or produced before final conversion recommendations.',
    estimatedCvrLift: 'Not estimated until review evidence and visual assets are verified.',
    approvalStatus: 'needs_human_review',
    blockers: blockers.map((item, index) => ({ rank: index + 1, relevance: index === 0 ? 5 : 4, ...item }))
  })
  return true
}

function writeImprovements(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'improvements')) return false
  const seeds = benefitSeeds(product)
  const improvements = [
    {
      improvement: 'Extract SKU-specific review themes before finalising PDP copy',
      productWeakness: 'No quote-level customer-language evidence attached yet',
      suggestedCopy: 'Do not publish final benefit copy from this queue row alone.'
    },
    {
      improvement: 'Map only source-backed/approved claims into clinically_shown_to',
      productWeakness: 'Compliance approval is still blocked for most catalogue rows',
      suggestedCopy: 'Use authorised claims only; avoid disease-treatment or unsupported efficacy language.'
    },
    {
      improvement: 'Produce and upload the assigned PDP visual assets',
      productWeakness: 'Image audit/photo brief can only be final after the actual files exist',
      suggestedCopy: 'Use the filename assignments as the production checklist, not as proof assets are live.'
    },
    ...seeds.slice(0, 2).map((seed: string) => ({
      improvement: `Validate customer demand around: ${seed}`,
      productWeakness: 'Benefit seed needs supporting reviews and market evidence',
      suggestedCopy: 'Turn into PDP language only after supporting source rows are attached.'
    }))
  ]
  writeJson(intelPath(sku, 'improvements.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_seeded_from_product_record',
    evidenceStatus: evidenceStatus(),
    approvalStatus: 'needs_human_review',
    improvements: improvements.map((item, index) => ({
      rank: index + 1,
      impact: index < 3 ? 5 : 3,
      difficulty: index < 3 ? 'Medium' : 'Low',
      ...item
    }))
  })
  return true
}

function writeImageAudit(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'image-audit')) return false
  const fields = product.metafields || {}
  const imageUrl = readJson('data/pipeline/product-images.json', {})?.[sku]?.image_url || ''
  const score = fields.pdpResults && fields.pdpResultsMobile && fields.pdpHowWeCompare ? 2.5 : 1.5
  writeJson(intelPath(sku, 'image-audit.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_pending_asset_visual_qa',
    evidenceStatus: {
      ...evidenceStatus(),
      imageAssets: 'filenames_assigned_but_files_missing_or_not_visual_verified'
    },
    imageUrl,
    imageDescription: 'Image audit queue scaffold. Actual product imagery and generated PDP assets must be inspected before scoring is final.',
    overallScore: {
      value: score,
      outOf: 5,
      confidence: 'low',
      verdict: 'Pending visual QA and asset upload.'
    },
    axes: {
      designQuality: { score, outOf: 5, label: 'Pending QA', notes: 'Cannot final-score until actual assets are present.' },
      perceivedValue: { score, outOf: 5, label: 'Pending QA', notes: 'Requires product/competitor visual inspection.' },
      messageClarity: { score, outOf: 5, label: 'Pending QA', notes: 'Requires checking filename assets and PDP context.' },
      messageStrength: { score, outOf: 5, label: 'Pending QA', notes: 'Requires proof that customer-language insights are represented visually.' }
    },
    priorityFixes: [
      `Produce/upload ${fields.pdpResults || `${sku.toLowerCase()}-results.png`}`,
      `Produce/upload ${fields.pdpResultsMobile || `${sku.toLowerCase()}-results-mobile.png`}`,
      `Produce/upload ${fields.pdpHowWeCompare || `${sku.toLowerCase()}-how-we-compare.png`}`,
      'Run visual QA against customer review themes before approving images'
    ]
  })
  return true
}

function writePhotoBrief(product: any) {
  const sku = product.sku
  if (!shouldWrite(sku, 'photo-brief')) return false
  const seeds = benefitSeeds(product)
  writeJson(intelPath(sku, 'photo-brief.json'), {
    sku,
    name: productName(product),
    generatedAt: now(),
    generatedBy: GENERATOR,
    coverage: 'catalogue_queue_pending_asset_production',
    evidenceStatus: {
      ...evidenceStatus(),
      imageAssets: 'brief_generated_from_product_record_not_final_art_direction'
    },
    priority: 'QUEUE - produce only after review themes and compliance copy are approved.',
    immediateAction: 'Use this as a production checklist scaffold; replace with SKU-specific art direction after source-backed themes are reviewed.',
    shotList: [
      {
        shotId: `${sku}-1`,
        type: 'Hero product',
        description: `Clean JustVitamins product hero for ${productName(product)} with packaging legible and no unsupported claims.`,
        purpose: 'Primary PDP asset',
        surface: 'Light neutral background',
        lighting: 'Soft diffused product lighting',
        props: []
      },
      {
        shotId: `${sku}-2`,
        type: 'Benefit/context image',
        description: `Visualise the strongest approved customer benefit/theme after evidence review. Current seed: ${seeds[0]}.`,
        purpose: 'PDP results/context asset',
        surface: 'Brand-consistent neutral or lifestyle setting',
        lighting: 'Natural soft light',
        props: []
      },
      {
        shotId: `${sku}-3`,
        type: 'Comparison/clarity image',
        description: 'Show format, dosage, or differentiator only after compliance-approved wording is available.',
        purpose: 'How-we-compare asset',
        surface: 'Clean comparison layout',
        lighting: 'Even studio light',
        props: []
      }
    ],
    mustCommunicate: seeds.slice(0, 5),
    mustNOTCommunicate: [
      'Unsupported medical/disease-treatment claims',
      'Unverified review counts or unapproved clinical language',
      'Any asset that differs from the actual JustVitamins product format'
    ],
    styling: {
      background: 'Clean JustVitamins-compatible neutral background',
      lighting: 'Soft, even, trustworthy product lighting',
      props: 'Minimal props; use only when they clarify approved benefits.'
    },
    aiGenerationNotes: {
      targetAesthetic: 'Clean, credible supplement PDP asset; final prompts require real product/reference imagery.',
      referencePrompt: `Create a clean PDP support image for ${productName(product)}. Keep claims neutral and leave copy areas editable until compliance approval.`
    },
    conversionBlockersAddressed: [
      'Creates a production queue for missing PDP assets',
      'Keeps unsupported benefit imagery blocked until evidence review',
      'Links image production to compliance approval rather than guessing'
    ]
  })
  return true
}

let written = 0
const byView: Record<string, number> = {
  'review-aspects': 0,
  'strengths-weaknesses': 0,
  'conversion-blockers': 0,
  improvements: 0,
  'image-audit': 0,
  'photo-brief': 0
}

for (const product of listProducts()) {
  const actions: [string, (product: any) => boolean][] = [
    ['review-aspects', writeReviewAspects],
    ['strengths-weaknesses', writeStrengthsWeaknesses],
    ['conversion-blockers', writeConversionBlockers],
    ['improvements', writeImprovements],
    ['image-audit', writeImageAudit],
    ['photo-brief', writePhotoBrief]
  ]
  for (const [view, fn] of actions) {
    if (fn(product)) {
      written += 1
      byView[view] += 1
    }
  }
}

console.log(`Catalogue intelligence queue files written: ${written}`)
for (const [view, count] of Object.entries(byView)) console.log(`${view}: ${count}`)
