#!/usr/bin/env node
/**
 * stripe-sync.mjs
 * ────────────────
 * Synchronise les produits de la BDD vers Stripe :
 *   1. Pour chaque produit avec un prix (price != null) :
 *      - Crée le Product Stripe (ou le retrouve via metadata.slug)
 *      - Crée le Price Stripe
 *      - Met à jour le stripePriceId dans la BDD
 *   2. Les produits sans prix sont ignorés
 *
 * Usage :
 *   node scripts/stripe-sync.mjs            # mode dry-run
 *   node scripts/stripe-sync.mjs --confirm  # exécution réelle
 */

import 'dotenv/config'
import Stripe from 'stripe'
import { PrismaClient } from '@prisma/client'

const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY
if (!STRIPE_SECRET_KEY) {
  console.error('❌ STRIPE_SECRET_KEY manquant dans .env')
  process.exit(1)
}

const stripe = new Stripe(STRIPE_SECRET_KEY)
const prisma = new PrismaClient()
const dryRun = !process.argv.includes('--confirm')

if (dryRun) {
  console.log('🔍 MODE DRY-RUN — rien ne sera créé ni modifié')
  console.log('   Ajouter --confirm pour exécuter réellement\n')
}

/**
 * Cherche un produit Stripe existant par metadata.slug
 */
async function findExistingStripeProduct(slug) {
  let hasMore = true
  let startingAfter = undefined

  while (hasMore) {
    const params = { limit: 100, active: true }
    if (startingAfter) params.starting_after = startingAfter

    const products = await stripe.products.list(params)

    for (const product of products.data) {
      if (product.metadata?.slug === slug) {
        return product
      }
    }

    hasMore = products.has_more
    if (products.data.length > 0) {
      startingAfter = products.data[products.data.length - 1].id
    }
  }

  return null
}

/**
 * Cherche un prix actif existant pour un produit Stripe
 * avec le bon montant et la bonne devise
 */
async function findExistingPrice(stripeProductId, amount, currency) {
  const prices = await stripe.prices.list({
    product: stripeProductId,
    active: true,
    limit: 100,
  })

  return prices.data.find(
    p => p.unit_amount === amount && p.currency === currency.toLowerCase()
  )
}

async function main() {
  // Récupérer tous les produits publiés avec un prix
  const products = await prisma.product.findMany({
    where: {
      isPublished: true,
      price: { not: null },
    },
    orderBy: { sortOrder: 'asc' },
  })

  if (products.length === 0) {
    console.log('ℹ️  Aucun produit avec un prix trouvé dans la BDD')
    return
  }

  console.log(`📦 ${products.length} produit(s) à synchroniser vers Stripe\n`)

  let created = 0
  let updated = 0
  let skipped = 0

  for (const product of products) {
    const priceCents = product.price
    const currency = product.currency.toLowerCase()

    console.log(`── ${product.productDisplayName} (${product.slug})`)
    console.log(`   Prix: ${priceCents / 100} ${currency.toUpperCase()}`)

    // 1. Chercher ou créer le Product Stripe
    let stripeProduct = await findExistingStripeProduct(product.slug)

    if (stripeProduct) {
      console.log(`   ✓ Produit Stripe existant: ${stripeProduct.id}`)

      if (!dryRun) {
        // Mettre à jour les infos du produit
        stripeProduct = await stripe.products.update(stripeProduct.id, {
          name: product.productDisplayName,
          description: product.description,
          images: product.ogImage ? [product.ogImage] : undefined,
          metadata: {
            slug: product.slug,
            stripeKey: product.stripeKey || product.slug,
            dbId: product.id,
          },
        })
        console.log(`   ✓ Produit Stripe mis à jour`)
      }
    } else {
      if (dryRun) {
        console.log(`   📌 Produit Stripe SERAIT créé`)
      } else {
        stripeProduct = await stripe.products.create({
          name: product.productDisplayName,
          description: product.description,
          images: product.ogImage ? [product.ogImage] : [],
          metadata: {
            slug: product.slug,
            stripeKey: product.stripeKey || product.slug,
            dbId: product.id,
          },
        })
        console.log(`   ✓ Produit Stripe créé: ${stripeProduct.id}`)
      }
    }

    // 2. Chercher ou créer le Price Stripe
    let stripePrice = null

    if (stripeProduct) {
      stripePrice = await findExistingPrice(stripeProduct.id, priceCents, currency)
    }

    if (stripePrice) {
      console.log(`   ✓ Prix Stripe existant: ${stripePrice.id} (${priceCents / 100} ${currency.toUpperCase()})`)

      // Vérifier si le stripePriceId dans la BDD est à jour
      if (product.stripePriceId === stripePrice.id) {
        console.log(`   ✓ BDD déjà à jour`)
        skipped++
      } else {
        if (dryRun) {
          console.log(`   📌 stripePriceId SERAIT mis à jour: ${product.stripePriceId || '(vide)'} → ${stripePrice.id}`)
          updated++
        } else {
          await prisma.product.update({
            where: { id: product.id },
            data: { stripePriceId: stripePrice.id },
          })
          console.log(`   ✓ BDD mise à jour: stripePriceId = ${stripePrice.id}`)
          updated++
        }
      }
    } else {
      // Créer un nouveau prix
      if (dryRun) {
        console.log(`   📌 Prix Stripe SERAIT créé: ${priceCents / 100} ${currency.toUpperCase()}`)
        console.log(`   📌 stripePriceId SERAIT mis à jour dans la BDD`)
        created++
      } else {
        stripePrice = await stripe.prices.create({
          product: stripeProduct.id,
          unit_amount: priceCents,
          currency: currency,
          metadata: {
            slug: product.slug,
            dbId: product.id,
          },
        })
        console.log(`   ✓ Prix Stripe créé: ${stripePrice.id}`)

        // 3. Mettre à jour le stripePriceId dans la BDD
        await prisma.product.update({
          where: { id: product.id },
          data: { stripePriceId: stripePrice.id },
        })
        console.log(`   ✓ BDD mise à jour: stripePriceId = ${stripePrice.id}`)
        created++
      }
    }

    console.log()
  }

  console.log('─'.repeat(50))
  if (dryRun) {
    console.log(`📊 Résumé (dry-run) :`)
    console.log(`   ${created} produit(s)/prix SERAIENT créés`)
    console.log(`   ${updated} stripePriceId SERAIENT mis à jour`)
    console.log(`   ${skipped} déjà synchronisé(s)`)
    console.log(`\n👉 Relancer avec --confirm pour exécuter`)
  } else {
    console.log(`✅ Synchronisation terminée :`)
    console.log(`   ${created} créé(s), ${updated} mis à jour, ${skipped} inchangé(s)`)
  }
}

main()
  .catch(err => {
    console.error('❌ Erreur:', err.message)
    process.exit(1)
  })
  .finally(() => prisma.$disconnect())
