/**
 * Project lifecycle routes — project-archive-complete (P059).
 * Mounted at /api/projects via projectRoutes in routes/projects/index.ts.
 *
 * Routes:
 *   GET  /:id/completion-summary → completion summary before marking complete
 *   POST /:id/complete   → mark project as completed
 *   POST /:id/archive    → archive a project
 *   POST /:id/unarchive  → restore an archived project to completed
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../../types'
import { requirePermission } from '../../middleware/guards'
import {
  getCompletionSummary,
  completeProject,
  archiveProjectLifecycle,
  reopenProject,
} from '@zync/db/queries'

// ── Zod schemas ────────────────────────────────────────────────────────────────

const completeProjectSchema = z.object({
  close_open_tasks: z.boolean().optional().default(false),
})

export const projectLifecycleRoutes = new Hono<AppEnv>()

projectLifecycleRoutes.get(
  '/:id/completion-summary',
  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 summary = await getCompletionSummary(db, session.tid, c.req.param('id'))
      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
    }
  },
)

// POST /api/projects/:id/complete
projectLifecycleRoutes.post(
  '/:id/complete',
  requirePermission('projects:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const projectId = c.req.param('id')
    const body = await c.req.json().catch(() => ({}))
    const parsed = completeProjectSchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Invalid request', issues: parsed.error.issues }, 400)
    }

    const db = c.get('db')
    const result = await completeProject(db, session.tid, projectId, session.sub, {
      closeOpenTasks: parsed.data.close_open_tasks,
    })

    if (!result.ok) {
      const status = result.error?.code === 'NOT_FOUND' ? 404 : 409
      return c.json({ error: result.error?.message, code: result.error?.code }, status)
    }

    return c.json({ project: result.project }, 200)
  },
)

// POST /api/projects/:id/archive
projectLifecycleRoutes.post(
  '/:id/archive',
  requirePermission('projects:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const projectId = c.req.param('id')
    const db = c.get('db')
    const result = await archiveProjectLifecycle(db, session.tid, projectId, session.sub)

    if (!result.ok) {
      const status = result.error?.code === 'NOT_FOUND' ? 404 : 409
      return c.json({ error: result.error?.message, code: result.error?.code }, status)
    }

    return c.json({ project: result.project }, 200)
  },
)

// POST /api/projects/:id/unarchive
projectLifecycleRoutes.post(
  '/:id/unarchive',
  requirePermission('projects:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const projectId = c.req.param('id')
    const db = c.get('db')
    const result = await reopenProject(db, session.tid, projectId, session.sub)

    if (!result.ok) {
      const status = result.error?.code === 'NOT_FOUND' ? 404 : 409
      return c.json({ error: result.error?.message, code: result.error?.code }, status)
    }

    return c.json({ project: result.project }, 200)
  },
)
