/**
 * Centralized Access Control Functions
 *
 * This module exports all access control functions used by collections.
 * By centralizing them here, we can:
 * 1. Test the actual production code
 * 2. Reuse access patterns across collections
 * 3. Ensure consistency in access control logic
 */

import type { Access, FieldAccess } from 'payload'

// Re-export tenant access functions
export { getTenantIdFromHost, tenantScopedPublicRead, authenticatedOnly } from '../tenantAccess'

// ============================================================================
// Super Admin Access
// ============================================================================

/**
 * Access control that only allows super admins
 */
export const superAdminOnly: Access = ({ req }) => {
  return Boolean((req.user as { isSuperAdmin?: boolean })?.isSuperAdmin)
}

/**
 * Access control that denies everyone (for system-generated content)
 */
export const denyAll: Access = () => false

// ============================================================================
// AuditLogs Access Functions
// ============================================================================

export const auditLogsAccess = {
  read: superAdminOnly,
  create: denyAll,
  update: denyAll,
  delete: denyAll,
}

// ============================================================================
// EmailLogs Access Functions
// ============================================================================

export const emailLogsReadAccess: Access = ({ req }) => {
  if (!req.user) return false
  // Super Admins see all
  if ((req.user as { isSuperAdmin?: boolean }).isSuperAdmin) return true
  // Regular users see only their tenant's logs
  return {
    tenant: {
      in: (req.user.tenants || []).map(
        (t: { tenant: { id: number } | number }) =>
          typeof t.tenant === 'object' ? t.tenant.id : t.tenant,
      ),
    },
  }
}

export const emailLogsAccess = {
  read: emailLogsReadAccess,
  create: denyAll,
  update: denyAll,
  delete: superAdminOnly,
}

// ============================================================================
// Pages Access Functions
// ============================================================================

export const pagesReadAccess: Access = ({ req }) => {
  if (req.user) return true // Authenticated see all
  return { status: { equals: 'published' } } // Public see published only
}

export const pagesWriteAccess: Access = ({ req }) => !!req.user

export const pagesAccess = {
  read: pagesReadAccess,
  create: pagesWriteAccess,
  update: pagesWriteAccess,
  delete: pagesWriteAccess,
}

// ============================================================================
// ConsentLogs Access Functions (API Key based)
// ============================================================================

/**
 * Creates an API key access function that handles both Headers object and plain Record types
 * @param envKey - The environment variable name containing the expected API key
 */
export function createApiKeyAccess(envKey: string): Access {
  return ({ req }) => {
    const expectedKey = process.env[envKey]
    if (!expectedKey) return false

    const headers = req.headers as Headers | Record<string, string | string[] | undefined>
    const apiKey =
      typeof headers.get === 'function'
        ? headers.get('x-api-key')
        : (headers as Record<string, string | string[] | undefined>)['x-api-key']

    // Strict validation: Header must exist and be non-empty
    if (!apiKey || typeof apiKey !== 'string') return false

    const trimmedKey = apiKey.trim()
    if (trimmedKey === '') return false

    return trimmedKey === expectedKey
  }
}

export const consentLogsCreateAccess = createApiKeyAccess('CONSENT_LOGGING_API_KEY')

// ============================================================================
// Monitoring Access Functions
// ============================================================================

export const monitoringSnapshotsAccess = {
  read: superAdminOnly,
  create: superAdminOnly,
  update: denyAll,
  delete: superAdminOnly,
}

export const monitoringLogsAccess = {
  read: superAdminOnly,
  create: superAdminOnly,
  update: denyAll,
  delete: superAdminOnly,
}

export const monitoringAlertRulesAccess = {
  read: superAdminOnly,
  create: superAdminOnly,
  update: superAdminOnly,
  delete: superAdminOnly,
}

export const monitoringAlertHistoryAccess = {
  read: superAdminOnly,
  create: superAdminOnly,
  update: superAdminOnly,
  delete: superAdminOnly,
}

// ============================================================================
// Field-Level Access Functions
// ============================================================================

/**
 * Field access that always denies read (for sensitive data like passwords)
 */
export const neverReadable: FieldAccess = () => false

/**
 * Field access that only allows super admins
 */
export const superAdminOnlyField: FieldAccess = ({ req }) => {
  return Boolean((req.user as { isSuperAdmin?: boolean })?.isSuperAdmin)
}

/**
 * Field access that requires authentication
 */
export const authenticatedOnlyField: FieldAccess = ({ req }) => {
  return !!req.user
}

/**
 * Field access that checks tenant membership
 * Used for fields that should only be accessible to users in the same tenant
 */
export const tenantMemberField: FieldAccess = ({ req, doc }) => {
  if (!req.user) return false
  if ((req.user as { isSuperAdmin?: boolean }).isSuperAdmin) return true

  const tenantId = doc?.tenant as number | { id: number } | undefined
  if (!tenantId) return false

  const docTenantId = typeof tenantId === 'object' ? tenantId.id : tenantId
  const userTenantIds = (req.user.tenants || []).map(
    (t: { tenant: { id: number } | number }) =>
      typeof t.tenant === 'object' ? t.tenant.id : t.tenant,
  )

  return userTenantIds.includes(docTenantId)
}
