/**
 * Credential service function tests
 * Tests prepareCredentialForInsert and transformToMetadata with provider field
 */

import { describe, it, expect, vi } from 'vitest'
import {
  prepareCredentialForInsert,
  transformToMetadata,
  type CreateCredentialParams
} from '../server/service'
import type { Database } from '../../../../supabase/database.types'

// Mock encryption module
vi.mock('../server/encryption', () => ({
  encryptCredential: vi.fn((value: string) => `encrypted:${value}`),
  decryptCredential: vi.fn((value: string) => value.replace('encrypted:', ''))
}))

type CredentialRow = Database['public']['Tables']['credentials']['Row']

describe('prepareCredentialForInsert', () => {
  const baseParams: CreateCredentialParams = {
    organizationId: 'org-123',
    name: 'test-cred',
    type: 'api-key',
    value: { apiKey: 'secret-key' },
    createdBy: 'user-456'
  }

  it('includes provider in insert data when provided', () => {
    const params: CreateCredentialParams = {
      ...baseParams,
      type: 'oauth',
      value: { accessToken: 'token', refreshToken: 'refresh' },
      provider: 'dropbox'
    }

    const result = prepareCredentialForInsert(params)

    expect(result.provider).toBe('dropbox')
  })

  it('sets provider to null when not provided', () => {
    const result = prepareCredentialForInsert(baseParams)

    expect(result.provider).toBeNull()
  })

  it('sets provider to null for non-OAuth credentials', () => {
    const params: CreateCredentialParams = {
      ...baseParams,
      type: 'api-key',
      // No provider field
    }

    const result = prepareCredentialForInsert(params)

    expect(result.provider).toBeNull()
  })

  it('handles all OAuth provider values correctly', () => {
    const providers = ['dropbox', 'notion', 'google-sheets']

    for (const provider of providers) {
      const params: CreateCredentialParams = {
        ...baseParams,
        type: 'oauth',
        provider
      }

      const result = prepareCredentialForInsert(params)

      expect(result.provider).toBe(provider)
    }
  })

  it('encrypts credential value', () => {
    const result = prepareCredentialForInsert(baseParams)

    expect(result.encrypted_value).toContain('encrypted:')
  })

  it('includes all required fields for database insert', () => {
    const params: CreateCredentialParams = {
      ...baseParams,
      provider: 'dropbox'
    }

    const result = prepareCredentialForInsert(params)

    expect(result).toEqual({
      organization_id: 'org-123',
      name: 'test-cred',
      type: 'api-key',
      encrypted_value: expect.stringContaining('encrypted:'),
      created_by: 'user-456',
      provider: 'dropbox'
    })
  })
})

describe('transformToMetadata', () => {
  const baseRow: CredentialRow = {
    id: 'cred-123',
    organization_id: 'org-456',
    name: 'test-cred',
    type: 'api-key',
    provider: null,
    encrypted_value: 'encrypted:value',
    created_at: '2026-02-02T00:00:00.000Z',
    updated_at: '2026-02-02T00:00:00.000Z',
    created_by: 'user-789'
  }

  it('converts null provider to undefined', () => {
    const result = transformToMetadata(baseRow)

    expect(result.provider).toBeUndefined()
  })

  it('preserves provider when set', () => {
    const row: CredentialRow = {
      ...baseRow,
      provider: 'dropbox'
    }

    const result = transformToMetadata(row)

    expect(result.provider).toBe('dropbox')
  })

  it('handles all OAuth provider values', () => {
    const providers = ['dropbox', 'notion', 'google-sheets']

    for (const provider of providers) {
      const row: CredentialRow = {
        ...baseRow,
        provider
      }

      const result = transformToMetadata(row)

      expect(result.provider).toBe(provider)
    }
  })

  it('returns correct metadata structure', () => {
    const row: CredentialRow = {
      ...baseRow,
      provider: 'notion'
    }

    const result = transformToMetadata(row)

    expect(result).toEqual({
      id: 'cred-123',
      name: 'test-cred',
      type: 'api-key',
      provider: 'notion',
      createdAt: '2026-02-02T00:00:00.000Z'
    })
  })

  it('excludes sensitive fields from metadata', () => {
    const result = transformToMetadata(baseRow)

    // These fields should not be in metadata
    expect(result).not.toHaveProperty('encrypted_value')
    expect(result).not.toHaveProperty('organization_id')
    expect(result).not.toHaveProperty('created_by')
    expect(result).not.toHaveProperty('updated_at')
  })
})
