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

const root = process.cwd()
const contentRoot = join(root, 'data', 'content')
const intelRoot = join(root, 'data', 'intelligence')

type Review = { comment?: string; stars?: number }

type CollectionConfig = {
  collection: string
  name: string
  skus: string[]
  keywords: string[]
  buttonText: string
  buttonLink: string
  backgroundColour: string
}

const configs: CollectionConfig[] = [
  {
    collection: 'vitamin-d',
    name: 'Vitamin D',
    skus: ['JV-D4000', 'JV-D1000'],
    keywords: ['vitamin d', 'sun', 'winter', 'blood', 'deficiency', 'doctor', 'gp', 'recommend'],
    buttonText: 'Shop Vitamin D',
    buttonLink: '/collections/vitamin-d',
    backgroundColour: '#F5E8C8'
  },
  {
    collection: 'joint-care',
    name: 'Joint Care',
    skus: ['JV-TURMERIC500'],
    keywords: ['joint', 'arthritis', 'pain', 'mobility', 'knee', 'rheumatoid', 'turmeric'],
    buttonText: 'Shop Joint Care',
    buttonLink: '/collections/joint-care',
    backgroundColour: '#E8D9B7'
  }
]

function readJson(path: string, fallback: any = null) {
  if (!existsSync(path)) return fallback
  return JSON.parse(readFileSync(path, 'utf8').replace(/^\uFEFF/, ''))
}
function writeJson(path: string, data: any) {
  writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf8')
}
function slug(value: string) {
  return String(value || '').toLowerCase().replace(/&/g, 'and').replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
}
function cleanQuote(value: string) {
  return String(value || '').replace(/\s+/g, ' ').trim()
}
function scoreReview(review: Review, cfg: CollectionConfig) {
  const comment = cleanQuote(review.comment || '')
  if (!comment || comment.length < 70 || comment.length > 260) return -999
  const lower = comment.toLowerCase()
  const keywordScore = cfg.keywords.reduce((score, keyword) => score + (lower.includes(keyword) ? 8 : 0), 0)
  const starScore = Number(review.stars || 0) * 5
  const usefulLength = Math.min(comment.length, 180) / 10
  const vaguePenalty = /great product|good product|excellent product/i.test(comment) && comment.length < 90 ? 20 : 0
  return keywordScore + starScore + usefulLength - vaguePenalty
}
function bestReview(cfg: CollectionConfig) {
  const candidates = []
  for (const sku of cfg.skus) {
    const reviews: Review[] = readJson(join(intelRoot, sku, '_raw_reviews.json'), [])
    for (let index = 0; index < reviews.length; index++) {
      const review = reviews[index]
      const score = scoreReview(review, cfg)
      if (score > -999) candidates.push({ sku, index, score, review })
    }
  }
  return candidates.sort((a, b) => b.score - a.score)[0] || null
}

const metaPath = join(contentRoot, 'metaobjects.json')
const collectionsPath = join(contentRoot, 'smart-collections.json')
const meta = readJson(metaPath, { definitions: {} })
const collections = readJson(collectionsPath, { collections: [] })
meta.definitions = meta.definitions || {}
meta.definitions.promo_card = Array.isArray(meta.definitions.promo_card) ? meta.definitions.promo_card : []

const created = []
for (const cfg of configs) {
  const selected = bestReview(cfg)
  if (!selected) {
    created.push({ collection: cfg.collection, status: 'no_suitable_review_found' })
    continue
  }
  const handle = `${slug(cfg.collection)}-feefo-review`
  const title = `"${cleanQuote(selected.review.comment || '')}"`
  const existingIndex = meta.definitions.promo_card.findIndex((row: any) => row.handle === handle)
  const row = {
    handle,
    name: `${cfg.name} Feefo review`,
    title,
    subtitle: 'Verified Feefo reviewer',
    button_text: cfg.buttonText,
    button_link: cfg.buttonLink,
    background_colour: cfg.backgroundColour,
    background_image: '',
    status: 'needs_review',
    source: `${selected.sku}/_raw_reviews.json index ${selected.index}, ${selected.review.stars || ''} stars`
  }
  if (existingIndex >= 0) meta.definitions.promo_card[existingIndex] = { ...meta.definitions.promo_card[existingIndex], ...row }
  else meta.definitions.promo_card.push(row)

  const collection = (collections.collections || []).find((item: any) => item.handle === cfg.collection)
  if (collection && !collection.promoCard) {
    collection.promoCard = `promo_card.${handle}`
    collection.status = 'needs_review'
  }
  created.push({ collection: cfg.collection, handle, sku: selected.sku, reviewIndex: selected.index, score: selected.score })
}

meta.generatedAt = new Date().toISOString()
collections.generatedAt = new Date().toISOString()
writeJson(metaPath, meta)
writeJson(collectionsPath, collections)
console.log(`Promo card candidates ready: ${created.filter(row => row.handle).length}`)
for (const row of created) console.log(JSON.stringify(row))
