import { db } from '../config/firebase'
import { RevenueCatEvent } from '../types'
import { getEnvValue } from '../config/env'
import * as admin from 'firebase-admin'

// Product IDs that grant premium access (comma-separated, configurable via env)
const DEFAULT_PREMIUM_PRODUCT_IDS = 'closer_premium_monthly,closer_premium_yearly'
const PRODUCT_ID_ALLOWLIST = new Set(
  getEnvValue('REVENUECAT_PREMIUM_PRODUCT_IDS')
    .split(',')
    .map(id => id.trim())
    .filter(id => id.length > 0)
)

if (PRODUCT_ID_ALLOWLIST.size === 0) {
  console.warn('[entitlement] No product IDs in allowlist - entitlement validation will be bypassed')
}

const PREMIUM_ACTIVE_TYPES = new Set([
  'INITIAL_PURCHASE',
  'RENEWAL',
  'PRODUCT_CHANGE',
  'TRANSFER',
  'UNCANCELLATION',
])

const PREMIUM_REVOKED_TYPES = new Set([
  'EXPIRATION',
  'CANCELLATION',
  'SUBSCRIBER_ALIAS',
])

const PREMIUM_ENTITLEMENT_ID = 'closer_premium'

/**
 * Checks if premium is currently active for a user.
 * Verifies both hasPremium flag AND expiration timestamp.
 */
export async function verifyPremiumActive(uid: string): Promise<boolean> {
  const userDoc = await db().collection('users').doc(uid).get()
  const data = userDoc.data()
  if (!data) return false

  // hasPremium must be true AND expiration must be in the future
  if (!data.hasPremium) return false

  const expiresAt = data.premiumExpiresAt as FirebaseFirestore.Timestamp | Date | undefined
  if (!expiresAt) return false

  const now = new Date()
  const expirationDate = typeof (expiresAt as any).toDate === 'function'
    ? (expiresAt as FirebaseFirestore.Timestamp).toDate()
    : (expiresAt as Date)
  return expirationDate > now
}

export async function syncEntitlement(event: RevenueCatEvent): Promise<void> {
  const { type, app_user_id: uid, id: eventId, product_id } = event.event

  // Idempotency: atomically create the event record. If it already exists,
  // another concurrent request processed it and we abort cleanly.
  const eventRef = db().collection('entitlement_events').doc(eventId)
  try {
    await eventRef.create({ processedAt: new Date() })
  } catch (err: any) {
    if (err?.code === 6 || err?.message?.includes('ALREADY_EXISTS')) {
      console.log(`[entitlement] skipping duplicate event: ${eventId}`)
      return
    }
    throw err
  }

  // Validate product_id against allowlist
  if (!PRODUCT_ID_ALLOWLIST.has(product_id)) {
    console.log(`[entitlement] ignored event for unknown product_id: ${product_id}`)
    return
  }

  // Verify entitlement_id matches expected premium entitlement
  const entitlementId = event.event.entitlement?.identifier || event.event.entitlement_id
  if (entitlementId !== PREMIUM_ENTITLEMENT_ID) {
    console.log(`[entitlement] ignored event for wrong entitlement: ${entitlementId} (expected: ${PREMIUM_ENTITLEMENT_ID})`)
    return
  }

  const userRef = db().collection('users').doc(uid)

  if (PREMIUM_ACTIVE_TYPES.has(type)) {
    const updates: { hasPremium: true; premiumExpiresAt?: FirebaseFirestore.Timestamp } = { hasPremium: true }

    // Store expiration timestamp if provided
    const expirationAtMs = event.event.expiration_at_ms
    if (expirationAtMs !== undefined) {
      updates.premiumExpiresAt = admin.firestore.Timestamp.fromMillis(expirationAtMs)
    }

    await userRef.update(updates)
    console.log(`[entitlement] hasPremium=true for ${uid} (${type})`)
    return
  }

  if (PREMIUM_REVOKED_TYPES.has(type)) {
    const updates: { hasPremium: false; premiumExpiresAt: null } = { hasPremium: false, premiumExpiresAt: null }

    await userRef.update(updates)
    console.log(`[entitlement] hasPremium=false for ${uid} (${type})`)
    return
  }

  console.log(`[entitlement] ignored event type: ${type}`)
}
