/**
 * Proposal routes — proposal-to-invoice-direct (wave-11).
 *
 * GET  /api/proposals/:id/invoice → existing invoice link check
 * POST /api/proposals/:id/invoice → create DRAFT invoice from proposal
 */
import { Hono } from 'hono'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission } from '../middleware/guards'
import {
  createDb,
  getProposalInvoiceLink,
  createInvoiceFromProposal,
  createInvoiceFromProposalSchema,
} from '@zync/db/queries'

export const proposalRoutes = new Hono<AppEnv>()

proposalRoutes.use('*', authMiddleware)

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

    const proposalId = c.req.param('id')
    const db = createDb(c.env)
    const link = await getProposalInvoiceLink(db, session.tid, proposalId)
    return c.json(link, 200)
  },
)

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

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

    const db = createDb(c.env)
    try {
      const result = await createInvoiceFromProposal(
        db,
        session.tid,
        proposalId,
        session.sub,
        parsed.data,
      )
      return c.json(result, 201)
    } catch (err) {
      if (err instanceof Error && err.message.includes('not found')) {
        return c.json({ error: 'Proposal not found' }, 404)
      }
      if (err instanceof Error && err.message === 'Forbidden') {
        return c.json({ error: 'Forbidden' }, 403)
      }
      if (err instanceof Error && err.message.includes('already exists')) {
        return c.json({ error: err.message }, 409)
      }
      if (err instanceof Error && err.message.includes('must be ACCEPTED')) {
        return c.json({ error: err.message }, 400)
      }
      throw err
    }
  },
)
