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

const mockGetProjectBurndown = vi.fn()

vi.mock('../src/middleware/guards', () => ({
  requirePermission: () => async (_c: unknown, next: () => Promise<void>) => next(),
  requireTier: () => async (_c: unknown, next: () => Promise<void>) => next(),
}))

vi.mock('../src/middleware/auth', () => ({
  authMiddleware: async (_c: unknown, next: () => Promise<void>) => next(),
}))

vi.mock('@zync/db/queries', async (importOriginal) => {
  const actual = await importOriginal<typeof import('@zync/db/queries')>()
  return {
    ...actual,
    createDb: vi.fn(() => ({})),
    getProjectBurndown: (...args: unknown[]) => mockGetProjectBurndown(...args),
  }
})

import { burndownRoute } from '../src/routes/burndown'

function appFor() {
  const app = new Hono<AppEnv>()
  app.use('*', async (c, next) => {
    c.set('session', {
      type: 'user',
      sub: 'user-1',
      tid: 'tenant-1',
      tier: 'business',
      role: 'OWNER',
      permissions: ['tasks:read'],
    })
    c.env = {} as AppEnv['Bindings']
    await next()
  })
  app.route('/api/projects', burndownRoute)
  return app
}

describe('burndown route', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockGetProjectBurndown.mockResolvedValue({
      totalEstimatedHours: 82,
      days: [{ date: '2026-05-20', loggedCumulative: 4, remaining: 78 }],
    })
  })

  it('returns burndown data for a valid request', async () => {
    const res = await appFor().request(
      '/api/projects/11111111-1111-4111-8111-111111111111/burndown?from=2026-05-20&to=2026-06-03',
    )
    const body = await res.json()

    expect(res.status).toBe(200)
    expect(body.totalEstimatedHours).toBe(82)
    expect(mockGetProjectBurndown).toHaveBeenCalledWith(
      {},
      'tenant-1',
      '11111111-1111-4111-8111-111111111111',
      '2026-05-20',
      '2026-06-03',
    )
  })

  it('rejects an inverted date window', async () => {
    const res = await appFor().request(
      '/api/projects/11111111-1111-4111-8111-111111111111/burndown?from=2026-06-03&to=2026-05-20',
    )

    expect(res.status).toBe(422)
    expect(mockGetProjectBurndown).not.toHaveBeenCalled()
  })
})
