/**
 * Field-Level Access Control Unit Tests
 *
 * Tests for field-level access control patterns.
 * Covers: SMTP password protection, sensitive field hiding, tenant membership
 *
 * IMPORTANT: These tests import the actual field access functions from @/lib/access
 * to ensure regressions in live collections are detected.
 */

import { describe, it, expect, vi } from 'vitest'
import type { FieldAccess, PayloadRequest } from 'payload'
import {
  createSuperAdmin,
  createTenantUser,
  createMockPayloadRequest,
  TEST_USERS,
} from '../../helpers/access-control-test-utils'

// ============================================================================
// Import REAL field access functions from centralized library
// ============================================================================

import {
  neverReadable,
  superAdminOnlyField,
  authenticatedOnlyField,
  tenantMemberField,
} from '@/lib/access'

// ============================================================================
// Field Access Function Types
// ============================================================================

interface MockFieldAccessArgs {
  req: ReturnType<typeof createMockPayloadRequest>
  doc?: Record<string, unknown>
  data?: Record<string, unknown>
  siblingData?: Record<string, unknown>
}

// ============================================================================
// Execute Field Access Helper
// ============================================================================

async function executeFieldAccess(
  accessFn: FieldAccess,
  args: MockFieldAccessArgs,
): Promise<boolean> {
  const result = await accessFn({
    req: args.req as unknown as PayloadRequest,
    doc: args.doc,
    data: args.data,
    siblingData: args.siblingData,
  })

  return result
}

// ============================================================================
// SMTP Password Field Tests (neverReadable)
// ============================================================================

describe('SMTP Password Field Access (neverReadable)', () => {
  describe('Read Access', () => {
    it('blocks read for super admin', async () => {
      const request = createMockPayloadRequest(TEST_USERS.superAdmin)
      const result = await executeFieldAccess(neverReadable, { req: request })

      expect(result).toBe(false)
    })

    it('blocks read for regular user', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser)
      const result = await executeFieldAccess(neverReadable, { req: request })

      expect(result).toBe(false)
    })

    it('blocks read for anonymous user', async () => {
      const request = createMockPayloadRequest(null)
      const result = await executeFieldAccess(neverReadable, { req: request })

      expect(result).toBe(false)
    })

    it('ensures password never appears in API response', async () => {
      // This tests the intent: no one should ever read the SMTP password via API
      const users = [
        TEST_USERS.superAdmin,
        TEST_USERS.porwollUser,
        TEST_USERS.multiTenantUser,
        null,
      ]

      for (const user of users) {
        const request = createMockPayloadRequest(user)
        const result = await executeFieldAccess(neverReadable, { req: request })
        expect(result).toBe(false)
      }
    })
  })
})

// ============================================================================
// Super Admin Only Field Tests
// ============================================================================

describe('Super Admin Only Field Access (superAdminOnlyField)', () => {
  it('grants access to super admin', async () => {
    const request = createMockPayloadRequest(TEST_USERS.superAdmin)
    const result = await executeFieldAccess(superAdminOnlyField, { req: request })

    expect(result).toBe(true)
  })

  it('denies access to regular tenant user', async () => {
    const request = createMockPayloadRequest(TEST_USERS.porwollUser)
    const result = await executeFieldAccess(superAdminOnlyField, { req: request })

    expect(result).toBe(false)
  })

  it('denies access to multi-tenant user without super admin', async () => {
    const request = createMockPayloadRequest(TEST_USERS.multiTenantUser)
    const result = await executeFieldAccess(superAdminOnlyField, { req: request })

    expect(result).toBe(false)
  })

  it('denies access to anonymous user', async () => {
    const request = createMockPayloadRequest(null)
    const result = await executeFieldAccess(superAdminOnlyField, { req: request })

    expect(result).toBe(false)
  })
})

// ============================================================================
// Authenticated Field Tests
// ============================================================================

describe('Authenticated Field Access (authenticatedOnlyField)', () => {
  it('grants access to any authenticated user', async () => {
    const users = [
      TEST_USERS.superAdmin,
      TEST_USERS.porwollUser,
      TEST_USERS.c2sUser,
      TEST_USERS.multiTenantUser,
    ]

    for (const user of users) {
      const request = createMockPayloadRequest(user)
      const result = await executeFieldAccess(authenticatedOnlyField, { req: request })
      expect(result).toBe(true)
    }
  })

  it('denies access to anonymous user', async () => {
    const request = createMockPayloadRequest(null)
    const result = await executeFieldAccess(authenticatedOnlyField, { req: request })

    expect(result).toBe(false)
  })
})

// ============================================================================
// Tenant Member Field Tests
// ============================================================================

describe('Tenant Member Field Access (tenantMemberField)', () => {
  describe('Authentication Checks', () => {
    it('denies anonymous users', async () => {
      const request = createMockPayloadRequest(null)
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: { tenant: 1 },
      })

      expect(result).toBe(false)
    })

    it('grants super admin access to any tenant document', async () => {
      const request = createMockPayloadRequest(TEST_USERS.superAdmin)
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: { tenant: 999 }, // Arbitrary tenant
      })

      expect(result).toBe(true)
    })
  })

  describe('Tenant Membership', () => {
    it('grants user access to own tenant document', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser) // tenant 1
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: { tenant: 1 },
      })

      expect(result).toBe(true)
    })

    it('denies user access to other tenant document', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser) // tenant 1 only
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: { tenant: 4 }, // c2s tenant
      })

      expect(result).toBe(false)
    })

    it('handles tenant as object format in document', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser)
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: { tenant: { id: 1 } },
      })

      expect(result).toBe(true)
    })

    it('multi-tenant user has access to all assigned tenants', async () => {
      const request = createMockPayloadRequest(TEST_USERS.multiTenantUser) // tenants 1, 4, 5

      const results = await Promise.all([
        executeFieldAccess(tenantMemberField, { req: request, doc: { tenant: 1 } }),
        executeFieldAccess(tenantMemberField, { req: request, doc: { tenant: 4 } }),
        executeFieldAccess(tenantMemberField, { req: request, doc: { tenant: 5 } }),
        executeFieldAccess(tenantMemberField, { req: request, doc: { tenant: 999 } }),
      ])

      expect(results).toEqual([true, true, true, false])
    })
  })

  describe('Edge Cases', () => {
    it('returns false when doc has no tenant', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser)
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: {},
      })

      expect(result).toBe(false)
    })

    it('returns false when doc is undefined', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser)
      const result = await executeFieldAccess(tenantMemberField, {
        req: request,
        doc: undefined,
      })

      expect(result).toBe(false)
    })
  })
})

// ============================================================================
// Security: Sensitive Data Protection Tests
// ============================================================================

describe('Sensitive Data Protection', () => {
  // List of sensitive field patterns that should never be readable via API
  const sensitiveFieldPatterns = [
    { name: 'SMTP Password (neverReadable)', access: neverReadable },
  ]

  describe.each(sensitiveFieldPatterns)('$name field', ({ access }) => {
    it('is never readable by super admin', async () => {
      const request = createMockPayloadRequest(TEST_USERS.superAdmin)
      const result = await executeFieldAccess(access, { req: request })
      expect(result).toBe(false)
    })

    it('is never readable by regular user', async () => {
      const request = createMockPayloadRequest(TEST_USERS.porwollUser)
      const result = await executeFieldAccess(access, { req: request })
      expect(result).toBe(false)
    })

    it('is never readable by anonymous user', async () => {
      const request = createMockPayloadRequest(null)
      const result = await executeFieldAccess(access, { req: request })
      expect(result).toBe(false)
    })
  })

  describe('Defense in Depth', () => {
    it('sensitive field access is stateless (no bypass via repeated requests)', async () => {
      const request = createMockPayloadRequest(TEST_USERS.superAdmin)

      // Multiple attempts should all fail
      for (let i = 0; i < 5; i++) {
        const result = await executeFieldAccess(neverReadable, { req: request })
        expect(result).toBe(false)
      }
    })

    it('sensitive field access ignores document context', async () => {
      const request = createMockPayloadRequest(TEST_USERS.superAdmin)
      const result = await executeFieldAccess(neverReadable, {
        req: request,
        doc: { isSuperAdmin: true, owner: 1, password: 'secret' },
      })

      expect(result).toBe(false)
    })
  })
})

// ============================================================================
// Field Access with Document Context (tenantMemberField)
// ============================================================================

describe('Field Access with Document Context', () => {
  it('grants access to document within user tenant', async () => {
    const user = createTenantUser([1], { id: 5 })
    const request = createMockPayloadRequest(user)
    const result = await executeFieldAccess(tenantMemberField, {
      req: request,
      doc: { tenant: 1 },
    })

    expect(result).toBe(true)
  })

  it('denies access to document outside user tenant', async () => {
    const user = createTenantUser([1], { id: 5 })
    const request = createMockPayloadRequest(user)
    const result = await executeFieldAccess(tenantMemberField, {
      req: request,
      doc: { tenant: 4 }, // Different tenant
    })

    expect(result).toBe(false)
  })

  it('grants access to super admin regardless of tenant', async () => {
    const request = createMockPayloadRequest(TEST_USERS.superAdmin)
    const result = await executeFieldAccess(tenantMemberField, {
      req: request,
      doc: { tenant: 999 }, // Any tenant
    })

    expect(result).toBe(true)
  })
})

// ============================================================================
// Comprehensive Field Access Matrix
// ============================================================================

describe('Field Access Matrix', () => {
  const allUsers = [
    { name: 'Super Admin', user: TEST_USERS.superAdmin },
    { name: 'Porwoll User', user: TEST_USERS.porwollUser },
    { name: 'Multi-Tenant User', user: TEST_USERS.multiTenantUser },
    { name: 'Anonymous', user: null },
  ]

  describe('neverReadable', () => {
    it.each(allUsers)('$name cannot read field', async ({ user }) => {
      const request = createMockPayloadRequest(user)
      const result = await executeFieldAccess(neverReadable, { req: request })
      expect(result).toBe(false)
    })
  })

  describe('superAdminOnlyField', () => {
    it.each(allUsers)('$name access is correctly evaluated', async ({ user }) => {
      const request = createMockPayloadRequest(user)
      const result = await executeFieldAccess(superAdminOnlyField, { req: request })

      if (user?.isSuperAdmin) {
        expect(result).toBe(true)
      } else {
        expect(result).toBe(false)
      }
    })
  })

  describe('authenticatedOnlyField', () => {
    it.each(allUsers)('$name access is correctly evaluated', async ({ user }) => {
      const request = createMockPayloadRequest(user)
      const result = await executeFieldAccess(authenticatedOnlyField, { req: request })

      if (user !== null) {
        expect(result).toBe(true)
      } else {
        expect(result).toBe(false)
      }
    })
  })
})
