import { beforeEach, describe, expect, it, vi } from 'vitest'
import { Hono } from 'hono'
import type { AppEnv } from '../src/types'

vi.mock('@zync/db/queries', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@zync/db/queries')>()
  return {
    ...actual,
    createDb: vi.fn(() => ({})),
    getMeView: vi.fn(),
    getUser2FAStatus: vi.fn().mockResolvedValue({ twoFactorEnabled: false }),
  }
})

import { getMeView } from '@zync/db/queries'

async function makeApp() {
  const { meRoute } = await import('../src/routes/auth/me')
  const app = new Hono<AppEnv>()
  app.use('*', async (c, next) => {
    c.set('session', {
      type: 'user',
      sub: 'user-1',
      tid: 'tenant-1',
      exp: Math.floor(Date.now() / 1000) + 3600,
    })
    await next()
  })
  app.route('/api/auth', meRoute)
  return app
}

describe('GET /api/auth/me i18n payload', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('prefers the user locale and user timezone when present', async () => {
    vi.mocked(getMeView).mockResolvedValue({
      id: 'user-1',
      email: 'u@example.com',
      name: 'User',
      avatarUrl: null,
      emailVerifiedAt: new Date(),
      tenantId: 'tenant-1',
      tenantSlug: 'tenant',
      tier: 'pro',
      onboardingCompleted: true,
      onboardingStep: 1,
      roleId: 'role-1',
      role: 'OWNER',
      membershipStatus: 'active',
      permissions: ['settings:write'],
      userLocale: 'he',
      tenantLocale: 'en',
      userTimezone: 'Asia/Jerusalem',
      tenantDefaultTimezone: 'America/New_York',
      countryCode: 'IL',
      userDefaultCurrency: 'ILS',
      tenantDefaultCurrency: 'USD',
    } as never)

    const app = await makeApp()
    const res = await app.fetch(new Request('http://localhost/api/auth/me'))
    const body = await res.json() as Record<string, unknown>

    expect(res.status).toBe(200)
    expect(body.locale).toBe('he')
    expect(body.timezone).toBe('Asia/Jerusalem')
    expect(body.countryCode).toBe('IL')
    expect(body.defaultCurrency).toBe('ILS')
  })

  it('falls back to the tenant locale and tenant defaults when user preferences are unset', async () => {
    vi.mocked(getMeView).mockResolvedValue({
      id: 'user-1',
      email: 'u@example.com',
      name: 'User',
      avatarUrl: null,
      emailVerifiedAt: new Date(),
      tenantId: 'tenant-1',
      tenantSlug: 'tenant',
      tier: 'pro',
      onboardingCompleted: true,
      onboardingStep: 1,
      roleId: 'role-1',
      role: 'OWNER',
      membershipStatus: 'active',
      permissions: ['settings:write'],
      userLocale: null,
      tenantLocale: 'he',
      userTimezone: null,
      tenantDefaultTimezone: 'Asia/Jerusalem',
      countryCode: 'IL',
      userDefaultCurrency: null,
      tenantDefaultCurrency: 'ILS',
    } as never)

    const app = await makeApp()
    const res = await app.fetch(new Request('http://localhost/api/auth/me'))
    const body = await res.json() as Record<string, unknown>

    expect(res.status).toBe(200)
    expect(body.locale).toBe('he')
    expect(body.timezone).toBe('Asia/Jerusalem')
    expect(body.defaultCurrency).toBe('ILS')
  })
})
