/**
 * Field permission settings routes — field-level-permissions (wave-11 leaf-E).
 * Mounted at /api/settings/field-permissions.
 *
 * GET / → current rules for tenant (permissions:write required)
 * PUT / → replace all rules for tenant (permissions:write + Business required)
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { TenantTier } from '@zync/types'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission, requireTier } from '../../middleware/guards'
import { getTenantFieldRules, saveTenantFieldRules } from '@zync/db/queries'

const ENTITY_TYPES = ['invoice', 'customer', 'project', 'contractor', 'lead'] as const
const FIELD_PERMISSION_REGISTRY: Record<string, readonly string[]> = {
  invoice: ['total', 'vat_amount', 'notes'],
  customer: ['phone', 'email', 'address', 'notes'],
  project: ['billing_config'],
  contractor: ['hourly_rate'],
  lead: ['estimated_value', 'score', 'notes'],
}

const fieldPermissionRuleSchema = z
  .object({
    entity_type: z.enum(ENTITY_TYPES),
    field_name: z.string().min(1),
    role: z.string().min(1),
    permission: z.enum(['visible', 'read_only', 'hidden']),
  })
  .superRefine((v, ctx) => {
    const allowed = FIELD_PERMISSION_REGISTRY[v.entity_type]
    if (!allowed?.includes(v.field_name)) {
      ctx.addIssue({
        code: 'custom',
        message: `field '${v.field_name}' is not configurable for entity '${v.entity_type}'`,
      })
    }
  })

const putFieldPermissionsSchema = z.array(fieldPermissionRuleSchema)

export const fieldPermissionsSettingsRoute = new Hono<AppEnv>()

fieldPermissionsSettingsRoute.use('*', authMiddleware)

// ── GET /api/settings/field-permissions ───────────────────────────────────────

fieldPermissionsSettingsRoute.get('/', requirePermission('permissions: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 rules = await getTenantFieldRules(db, session.tid)
  return c.json(rules, 200)
})

// ── PUT /api/settings/field-permissions ───────────────────────────────────────

fieldPermissionsSettingsRoute.put(
  '/',
  requirePermission('permissions:write'),
  requireTier(TenantTier.BUSINESS),
  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 = putFieldPermissionsSchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const db = c.get('db')
    await saveTenantFieldRules(db, session.tid, session.sub, parsed.data)
    return c.json(parsed.data.filter((rule) => rule.permission !== 'visible'), 200)
  },
)
