/**
 * Time entry locking routes — time-entry-locking (wave-8 leaf 8).
 * Mounted at /api/time-entries in apps/zync-api/src/routes/index.ts.
 *
 * Routes:
 *   POST /time-entries/lock    → lock a batch of entries (time:manage)
 *   POST /time-entries/unlock  → unlock a batch of entries (time:manage)
 *   GET  /time-entries/locked  → list locked entries for a date range (time:read)
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requireModuleEnabled } from '../../middleware/require-module-enabled'
import { requirePermission } from '../../middleware/guards'
import {
  createDb,
  lockTimeEntries,
  unlockTimeEntries,
  getLockedEntries,
} from '@zync/db/queries'

// ── Schemas ────────────────────────────────────────────────────────────────────

const lockBodySchema = z.object({
  ids: z.array(z.string().uuid()).min(1).max(500),
})

const lockedQuerySchema = z.object({
  start: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Expected YYYY-MM-DD'),
  end: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Expected YYYY-MM-DD'),
})

// ── Router ────────────────────────────────────────────────────────────────────

export const timeLockingRoutes = new Hono<AppEnv>()

timeLockingRoutes.use('*', authMiddleware)
timeLockingRoutes.use('*', requireModuleEnabled('time_management'))

// ── POST /lock ────────────────────────────────────────────────────────────────

timeLockingRoutes.post(
  '/lock',
  requirePermission('time:manage'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const body = await c.req.json().catch(() => null)
    const parsed = lockBodySchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const db = createDb(c.env)
    const result = await lockTimeEntries(db, session.tid, session.sub, parsed.data.ids)

    return c.json({ ok: true, lockedCount: result.lockedCount, skippedIds: result.skippedIds }, 200)
  },
)

// ── POST /unlock ──────────────────────────────────────────────────────────────

timeLockingRoutes.post(
  '/unlock',
  requirePermission('time:manage'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const body = await c.req.json().catch(() => null)
    const parsed = lockBodySchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const db = createDb(c.env)
    const result = await unlockTimeEntries(db, session.tid, session.sub, parsed.data.ids)

    return c.json(
      { ok: true, unlockedCount: result.lockedCount, skippedIds: result.skippedIds },
      200,
    )
  },
)

// ── GET /locked ───────────────────────────────────────────────────────────────

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

    const raw = Object.fromEntries(new URL(c.req.url).searchParams.entries())
    const parsed = lockedQuerySchema.safeParse(raw)
    if (!parsed.success) {
      return c.json({ error: 'Invalid query params', issues: parsed.error.issues }, 400)
    }

    const { start, end } = parsed.data
    const db = createDb(c.env)
    const entries = await getLockedEntries(
      db,
      session.tid,
      new Date(start + 'T00:00:00Z'),
      new Date(end + 'T23:59:59Z'),
    )

    return c.json({ entries }, 200)
  },
)
