import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import {
  fetchSanityProductForSync,
  syncSanityProductToMedusa,
  type SanityProductSyncPayload,
} from "../../../../../lib/sanity-product-sync"

type SanityWebhookBody = {
  _id?: string
  _type?: string
  operation?: string
  product?: SanityProductSyncPayload
} & Partial<SanityProductSyncPayload>

type SanityWebhookMetrics = {
  total: number
  blocked: number
  skipped: number
  synced: number
  failed: number
  windowStartedAt: number
}

const globalStore = globalThis as typeof globalThis & {
  __sanityWebhookMetrics__?: SanityWebhookMetrics
}

const metrics = globalStore.__sanityWebhookMetrics__ ?? {
  total: 0,
  blocked: 0,
  skipped: 0,
  synced: 0,
  failed: 0,
  windowStartedAt: Date.now(),
}

globalStore.__sanityWebhookMetrics__ = metrics

function readExpectedSecret() {
  return process.env.SANITY_WEBHOOK_SECRET || ""
}

function isDraftId(value: string) {
  return value.startsWith("drafts.")
}

function logWebhookMetrics(event: string, details: Record<string, unknown>) {
  console.info("[sanity-webhook]", event, details)
}

function rotateMetricsWindowIfNeeded() {
  const now = Date.now()
  if (now - metrics.windowStartedAt < 60_000) {
    return
  }

  logWebhookMetrics("minute_summary", {
    total: metrics.total,
    blocked: metrics.blocked,
    skipped: metrics.skipped,
    synced: metrics.synced,
    failed: metrics.failed,
    windowStartedAt: new Date(metrics.windowStartedAt).toISOString(),
    windowEndedAt: new Date(now).toISOString(),
  })

  metrics.total = 0
  metrics.blocked = 0
  metrics.skipped = 0
  metrics.synced = 0
  metrics.failed = 0
  metrics.windowStartedAt = now
}

export async function POST(req: MedusaRequest<SanityWebhookBody>, res: MedusaResponse) {
  rotateMetricsWindowIfNeeded()
  metrics.total += 1

  const expectedSecret = readExpectedSecret()
  const receivedSecret = String(req.headers["x-sanity-webhook-secret"] || "")

  if (expectedSecret && receivedSecret !== expectedSecret) {
    metrics.blocked += 1
    logWebhookMetrics("unauthorized", {
      total: metrics.total,
      blocked: metrics.blocked,
    })
    return res.status(401).json({ message: "Invalid Sanity webhook secret." })
  }

  const payload = (req.body?.product || req.body || {}) as SanityProductSyncPayload
  const documentId = String(payload._id || req.body?._id || "")
  const documentType = String((req.body?.product as any)?._type || req.body?._type || "")
  const operation = String(req.body?.operation || "")

  if (!documentId || documentType && documentType !== "product") {
    metrics.skipped += 1
    logWebhookMetrics("skipped_unsupported", {
      total: metrics.total,
      skipped: metrics.skipped,
      documentId,
      documentType,
      operation,
    })
    return res.status(202).json({ ok: true, skipped: true, reason: "Unsupported webhook payload." })
  }

  if (isDraftId(documentId)) {
    metrics.skipped += 1
    logWebhookMetrics("skipped_draft", {
      total: metrics.total,
      skipped: metrics.skipped,
      documentId,
      operation,
    })
    return res.status(202).json({ ok: true, skipped: true, reason: "Draft document ignored." })
  }

  try {
    logWebhookMetrics("received", {
      total: metrics.total,
      documentId,
      operation,
    })

    const fullProduct = await fetchSanityProductForSync(documentId)

    if (!fullProduct) {
      metrics.skipped += 1
      logWebhookMetrics("skipped_missing_published_product", {
        total: metrics.total,
        skipped: metrics.skipped,
        documentId,
        operation,
      })
      return res.status(202).json({ ok: true, skipped: true, reason: "Published product not found in Sanity." })
    }

    const result = await syncSanityProductToMedusa(req.scope as any, {
      ...fullProduct,
      _id: documentId,
    }, {
      allowSanityWriteback: false,
    })

    metrics.synced += 1
    logWebhookMetrics("synced", {
      total: metrics.total,
      synced: metrics.synced,
      documentId,
      operation,
      action: result.action,
      handle: result.handle,
    })

    return res.status(200).json({ ok: true, ...result })
  } catch (error) {
    metrics.failed += 1
    logWebhookMetrics("failed", {
      total: metrics.total,
      failed: metrics.failed,
      documentId,
      operation,
      message: error instanceof Error ? error.message : "Sanity product sync failed.",
    })

    return res.status(400).json({
      ok: false,
      message: error instanceof Error ? error.message : "Sanity product sync failed.",
    })
  }
}
