import Fastify from 'fastify'
import cors from '@fastify/cors'
import Stripe from 'stripe'
import { createClient } from '@sanity/client'
import dotenv from 'dotenv'

dotenv.config()

// ── Sanity client ──────────────────────────────────────────────────────────
const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID,
  dataset: process.env.SANITY_DATASET || 'production',
  apiVersion: '2024-01-01',
  useCdn: false, // Server-side: always fresh data
  token: process.env.SANITY_API_TOKEN, // Optional: for authenticated reads
})

// ── Stripe ─────────────────────────────────────────────────────────────────
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY ?? '')
const DOMAIN = process.env.DOMAIN ?? 'http://localhost:4321'

// ── Fastify ────────────────────────────────────────────────────────────────
const app = Fastify({ logger: true, trustProxy: true })
await app.register(cors, { origin: '*', methods: ['GET', 'POST'] })

// ── Webhook Stripe ─────────────────────────────────────────────────────────
app.post('/api/webhook', {
  config: { rawBody: true },
  onRequest: (request, reply, done) => {
    request.rawBody = ''
    request.req.on('data', chunk => { request.rawBody += chunk })
    request.req.on('end', done)
  },
}, async (request, reply) => {
  const sig = request.headers['stripe-signature']
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET
  if (!sig || !webhookSecret) return reply.code(400).send('Missing signature')

  let event
  try {
    event = stripe.webhooks.constructEvent(request.rawBody, sig, webhookSecret)
  } catch {
    return reply.code(400).send('Webhook Error')
  }

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object
    if (session.payment_status === 'paid') {
      app.log.info(
        `✓ Paiement confirmé — ${session.id} — ${session.customer_details?.email} — ${session.metadata?.product}`
      )
    }
  }

  return { received: true }
})

// ── Health check ────────────────────────────────────────────────────────────
app.get('/api/health', async () => ({ status: 'ok' }))

// ── Checkout Stripe ─────────────────────────────────────────────────────────
app.post('/api/checkout', async (request, reply) => {
  const { product: slug, email } = request.body ?? {}

  if (!slug) return reply.code(400).send({ error: 'Produit manquant' })

  // Fetch product from Sanity
  const product = await sanity.fetch(
    `*[_type == "product" && slug.current == $slug && isPublished == true][0]{
      productDisplayName,
      description,
      price,
      currency,
      "imageUrl": images[0].asset->url,
      "slug": slug.current
    }`,
    { slug }
  )

  if (!product || !product.price) {
    return reply.code(404).send({ error: 'Produit non disponible' })
  }

  try {
    const session = await stripe.checkout.sessions.create({
      mode: 'payment',
      payment_method_types: ['card', 'link'],
      line_items: [{
        price_data: {
          currency: (product.currency || 'EUR').toLowerCase(),
          product_data: {
            name: product.productDisplayName,
            description: product.description?.substring(0, 500) || undefined,
            images: product.imageUrl ? [product.imageUrl] : [],
          },
          unit_amount: product.price,
        },
        quantity: 1,
      }],
      metadata: { product: slug },
      success_url: `${DOMAIN}/success?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${DOMAIN}/#collection`,
      locale: 'fr',
      customer_email: email ?? undefined,
      custom_text: {
        submit: { message: 'Pièce unique — fabriquée à Paris. Délai : 6 à 8 semaines.' },
      },
    })
    return { url: session.url }
  } catch (err) {
    app.log.error(err)
    return reply.code(500).send({ error: err.message })
  }
})

// ── Vérification session ────────────────────────────────────────────────────
app.get('/api/session/:id', async (request) => {
  const session = await stripe.checkout.sessions.retrieve(request.params.id, {
    expand: ['payment_intent.latest_charge'],
  })
  const charge = session.payment_intent?.latest_charge
  return {
    status: session.payment_status,
    amount: session.amount_total,
    currency: session.currency,
    customer_email: session.customer_details?.email ?? null,
    product: session.metadata?.product ?? null,
    receipt_url: charge?.receipt_url ?? null,
  }
})

// ── Start ───────────────────────────────────────────────────────────────────
try {
  await app.listen({ port: process.env.FASTIFY_PORT ?? process.env.PORT ?? 3000, host: '0.0.0.0' })
} catch (err) {
  app.log.error(err)
  process.exit(1)
}
