import { afterEach, describe, expect, test } from 'bun:test'
import { createTempHome } from '../helpers/temp-env'
import { startFakeRegistry } from '../helpers/fake-registry'
import { runCli } from '../helpers/run-cli'

let registry: { url: string; stop: () => void } | undefined

afterEach(() => {
  registry?.stop()
  registry = undefined
})

describe('whoami command', () => {
  test('not logged in — exits with EXIT.auth and prints not logged in', async () => {
    const { home } = await createTempHome()
    const env = { HOME: home, USERPROFILE: home }

    const result = await runCli(['whoami'], env)

    expect(result.exitCode).toBe(2)
    expect(result.stderr).toContain('not logged in')
  })

  test('happy path — human output contains handle and displayName', async () => {
    registry = await startFakeRegistry({
      user: { handle: 'testuser', displayName: 'Test User', email: 'test@example.com' }
    })
    const { home } = await createTempHome()
    const env = { HOME: home, USERPROFILE: home }

    // Login first to store credentials
    const loginResult = await runCli(
      ['login', '--registry', registry.url, '--token', 'sk_ok'],
      env,
    )
    expect(loginResult.exitCode).toBe(0)

    // Now run whoami
    const result = await runCli(['whoami'], env)

    expect(result.exitCode).toBe(0)
    expect(result.stdout).toContain('testuser')
    expect(result.stdout).toContain('Test User')
  })

  test('--json flag — output is valid JSON with ok:true and user fields', async () => {
    registry = await startFakeRegistry({
      user: { handle: 'testuser', displayName: 'Test User', email: 'test@example.com' }
    })
    const { home } = await createTempHome()
    const env = { HOME: home, USERPROFILE: home }

    // Login first to store credentials
    const loginResult = await runCli(
      ['login', '--registry', registry.url, '--token', 'sk_ok'],
      env,
    )
    expect(loginResult.exitCode).toBe(0)

    // Now run whoami --json
    const result = await runCli(['whoami', '--json'], env)

    expect(result.exitCode).toBe(0)
    const json = JSON.parse(result.stdout)
    expect(json.ok).toBe(true)
    expect(json.handle).toBe('testuser')
    expect(json.displayName).toBe('Test User')
  })

  test('--token override — works without prior login', async () => {
    registry = await startFakeRegistry({
      user: { handle: 'testuser', displayName: 'Test User', email: 'test@example.com' }
    })
    const { home } = await createTempHome()
    const env = { HOME: home, USERPROFILE: home }

    // No login — pass token directly
    const result = await runCli(
      ['whoami', '--token', 'sk_ok', '--registry', registry.url],
      env,
    )

    expect(result.exitCode).toBe(0)
    expect(result.stdout).toContain('testuser')
  })

  test('auth failure from server — exits with EXIT.auth', async () => {
    registry = await startFakeRegistry({ failures: { whoami: 'auth' } })
    const { home } = await createTempHome()
    const env = { HOME: home, USERPROFILE: home }

    // Pass a bad token explicitly so the server returns 401
    const result = await runCli(
      ['whoami', '--token', 'sk_bad', '--registry', registry.url],
      env,
    )

    expect(result.exitCode).toBe(2)
    expect(result.stderr.toLowerCase()).toContain('authentication failed')
  })
})
