/**
 * Lead Forms routes — marketing-leads-pipeline.
 * Mounted at /api/marketing/forms (behind authMiddleware in router.ts).
 * Business+ tier gate applied per-route.
 *
 * GET    /              list forms
 * POST   /              create form (Business+)
 * GET    /:id           form detail
 * PATCH  /:id           update form (slug immutable after first submission)
 * DELETE /:id           delete form
 * GET    /:id/embed     embed snippet + instructions
 * GET    /:id/submissions  paginated submissions list
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { requirePermission } from '../../middleware/guards'
import {
  listLeadForms,
  getLeadForm,
  createLeadForm,
  updateLeadForm,
  deleteLeadForm,
  listLeadFormSubmissions,
  createLeadFormSchema,
  updateLeadFormSchema,
} from '@zync/db/queries'

export const formsRoute = new Hono<AppEnv>()

// ── List forms ────────────────────────────────────────────────────────────────

// GET /api/marketing/forms
formsRoute.get('/', requirePermission('marketing: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')

  const forms = await listLeadForms(db, session.tid)
  return c.json({ forms })
})

// ── Create form ───────────────────────────────────────────────────────────────

// POST /api/marketing/forms
formsRoute.post(
  '/',
  requirePermission('marketing:write'),
  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')

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

    // Business+ tier gate (fail-closed: missing tier → deny)
    if (!session.tier || !['business', 'enterprise'].includes(session.tier)) {
      return c.json({ error: 'Lead forms require Business plan or higher', upgrade: true }, 403)
    }

    const form = await createLeadForm(db, session.tid, session.sub, parsed.data)
    return c.json({ form }, 201)
  },
)

// ── Form detail ───────────────────────────────────────────────────────────────

// GET /api/marketing/forms/:id
formsRoute.get('/:id', requirePermission('marketing: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')
  const { id } = c.req.param()

  const form = await getLeadForm(db, session.tid, id)
  if (!form) return c.json({ error: 'Not found' }, 404)
  return c.json({ form })
})

// ── Update form ───────────────────────────────────────────────────────────────

// PATCH /api/marketing/forms/:id
formsRoute.patch(
  '/:id',
  requirePermission('marketing:write'),
  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')
    const { id } = c.req.param()

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

    const existing = await getLeadForm(db, session.tid, id)
    if (!existing) return c.json({ error: 'Not found' }, 404)

    // Slug is immutable after first submission
    if (input.slug && input.slug !== existing.slug) {
      if (existing.submissionCount > 0) {
        return c.json(
          { error: 'Slug cannot be changed after form has received submissions' },
          422,
        )
      }
    }

    const form = await updateLeadForm(db, session.tid, id, input)
    return c.json({ form })
  },
)

// ── Delete form ───────────────────────────────────────────────────────────────

// DELETE /api/marketing/forms/:id
formsRoute.delete('/:id', requirePermission('marketing:write'), 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')
  const { id } = c.req.param()

  const existing = await getLeadForm(db, session.tid, id)
  if (!existing) return c.json({ error: 'Not found' }, 404)

  await deleteLeadForm(db, session.tid, id)
  return c.json({ ok: true })
})

// ── Embed code ────────────────────────────────────────────────────────────────

// GET /api/marketing/forms/:id/embed
formsRoute.get('/:id/embed', requirePermission('marketing: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')
  const { id } = c.req.param()

  const form = await getLeadForm(db, session.tid, id)
  if (!form) return c.json({ error: 'Not found' }, 404)

  // Embed code: iframe pointing to the public form page on zync.is
  const tenantSlug = (session as { tenantSlug?: string }).tenantSlug ?? session.tid
  const publicUrl = `https://zync.is/f/${form.slug}?tenant=${tenantSlug}`
  const iframeSnippet = `<iframe src="${publicUrl}" width="100%" height="600" frameborder="0" style="border:none;overflow:hidden" scrolling="no"></iframe>`
  const scriptSnippet = `<script src="https://zync.is/embed.js" data-form="${form.slug}" data-tenant="${tenantSlug}" integrity="__EMBED_JS_SRI__" crossorigin="anonymous" async></script>`

  return c.json({
    publicUrl,
    iframeSnippet,
    scriptSnippet,
  })
})

// ── Submissions list ──────────────────────────────────────────────────────────

// GET /api/marketing/forms/:id/submissions
formsRoute.get('/:id/submissions', requirePermission('marketing: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')
  const { id } = c.req.param()

  const form = await getLeadForm(db, session.tid, id)
  if (!form) return c.json({ error: 'Not found' }, 404)

  const limit = Math.min(Number(c.req.query('limit') ?? 50), 100)
  const cursor = c.req.query('cursor')
  const result = await listLeadFormSubmissions(db, session.tid, id, limit, cursor)

  return c.json(result)
})
