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

const mockListTaskMessages = vi.fn()
const mockCreateTaskMessage = vi.fn()
const mockSoftDeleteTaskMessage = vi.fn()
const mockReparentAttachments = vi.fn()
const mockListTaskAudit = vi.fn()
const mockCreateNotification = vi.fn()
const mockGetTask = vi.fn()
const mockPublishRealtimeEvent = vi.fn()

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

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

vi.mock('../src/middleware/require-module-enabled', () => ({
  requireModuleEnabled: () => 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,
    listTaskMessages: (...args: unknown[]) => mockListTaskMessages(...args),
    createTaskMessage: (...args: unknown[]) => mockCreateTaskMessage(...args),
    softDeleteTaskMessage: (...args: unknown[]) => mockSoftDeleteTaskMessage(...args),
    reparentAttachments: (...args: unknown[]) => mockReparentAttachments(...args),
    listTaskAudit: (...args: unknown[]) => mockListTaskAudit(...args),
    createNotification: (...args: unknown[]) => mockCreateNotification(...args),
    getTask: (...args: unknown[]) => mockGetTask(...args),
  }
})

vi.mock('@zync/realtime/server', () => ({
  publishRealtimeEvent: (...args: unknown[]) => mockPublishRealtimeEvent(...args),
}))

import { taskMessagesRouter } from '../src/routes/task-messages'

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

describe('task messages routes', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('returns 404 for GET /api/tasks/:id/messages when task is not owned by tenant', async () => {
    mockGetTask.mockResolvedValue(null)

    const res = await appFor().request('/api/tasks/task-404/messages')

    expect(res.status).toBe(404)
    expect(mockListTaskMessages).not.toHaveBeenCalled()
  })

  it('returns 404 for GET /api/tasks/:id/audit when task is not owned by tenant', async () => {
    mockGetTask.mockResolvedValue(null)

    const res = await appFor().request('/api/tasks/task-404/audit')

    expect(res.status).toBe(404)
    expect(mockListTaskAudit).not.toHaveBeenCalled()
  })
})
