/**
 * Project hours & retainer-ledger API routes — projects module.
 * Mounted at /api/projects (behind authMiddleware + requireModuleEnabled in router).
 *
 * GET    /:id/hours           hour summary { this_month, all_time }
 * GET    /:id/retainer-months retainer ledger (empty array for non-retainer projects)
 */
import { Hono } from 'hono'
import {
  getProjectHours,
  listRetainerMonths,
  getProjectTasksWithActualHours,
  getProjectEstimateSummary,
} from '@zync/db/queries'
import type { AppEnv } from '../../types'
import { requirePermission } from '../../middleware/guards'

export const projectReportsRoute = new Hono<AppEnv>()

function hasTenantWideProjectVisibility(role: string | null | undefined): boolean {
  return role === 'OWNER' || role === 'ADMIN' || role === 'VIEWER'
}

// GET /api/projects/:id/hours
projectReportsRoute.get('/:id/hours', requirePermission('projects:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = c.get('db')
  try {
    const hours = await getProjectHours(db, session.tid, c.req.param('id'), {
      fullVisibility: hasTenantWideProjectVisibility(session.role),
      userId: session.sub,
    })
    return c.json(hours, 200)
  } catch (err) {
    if (err instanceof Error && err.message === 'Project not found') {
      return c.json({ error: 'Not found' }, 404)
    }
    throw err
  }
})

// GET /api/projects/:id/retainer-months
// Returns empty array (not an error) for non-retainer projects
projectReportsRoute.get(
  '/:id/retainer-months',
  requirePermission('projects:read'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const db = c.get('db')
    try {
      const months = await listRetainerMonths(db, session.tid, c.req.param('id'), {
        fullVisibility: hasTenantWideProjectVisibility(session.role),
        userId: session.sub,
      })
      return c.json(months, 200)
    } catch (err) {
      if (err instanceof Error && err.message === 'Project not found') {
        return c.json({ error: 'Not found' }, 404)
      }
      throw err
    }
  },
)

projectReportsRoute.get('/:id/tasks', requirePermission('tasks:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = c.get('db')
  try {
    const tasks = await getProjectTasksWithActualHours(db, session.tid, c.req.param('id'), {
      fullVisibility: hasTenantWideProjectVisibility(session.role),
      userId: session.sub,
    })
    return c.json({ data: tasks }, 200)
  } catch (err) {
    if (err instanceof Error && err.message === 'Project not found') {
      return c.json({ error: 'Not found' }, 404)
    }
    throw err
  }
})

projectReportsRoute.get('/:id/summary', requirePermission('tasks:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = c.get('db')
  try {
    const summary = await getProjectEstimateSummary(db, session.tid, c.req.param('id'), {
      fullVisibility: hasTenantWideProjectVisibility(session.role),
      userId: session.sub,
    })
    return c.json(summary, 200)
  } catch (err) {
    if (err instanceof Error && err.message === 'Project not found') {
      return c.json({ error: 'Not found' }, 404)
    }
    throw err
  }
})
