/**
 * Admin subscription routes — zync-subscription spec (Task 10).
 *
 * Mounted under /api/admin/tenants/:slug/subscription.
 *
 * GET   /api/admin/tenants/:slug/subscription    Fetch tenant subscription record
 * PATCH /api/admin/tenants/:slug/subscription    Manually set tier/status (manual provisioning)
 *
 * Only accessible by verified admin sessions (type='admin', totp_verified=true).
 * This is the provisioning path for Enterprise and White Label tenants.
 * All PATCH operations are audit-logged with actor = admin user id.
 * Zod validation on PATCH body.
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { adminAuthMiddleware } from '../middleware/admin-auth'
import { requireAdminSession } from '../middleware/guards'
import {
  createDb,
  getSubscriptionByTenantSlug,
  getTenantIdBySlug,
  upsertAdminSubscription,
  logAdminSubscriptionOverride,
} from '@zync/db/queries'
import { syncTierToTenant } from '@zync/payments'
import { TenantTier } from '@zync/types'
import type { AdminSessionPayload } from '@zync/types'
import type { AppEnv } from '../types'

export const adminSubscriptionRoute = new Hono<AppEnv>()

// Apply admin auth middleware to all routes
adminSubscriptionRoute.use('*', adminAuthMiddleware)
adminSubscriptionRoute.use('*', requireAdminSession())

// ---------------------------------------------------------------------------
// GET /api/admin/tenants/:slug/subscription
// ---------------------------------------------------------------------------

adminSubscriptionRoute.get('/:slug/subscription', async (c) => {
  const { slug } = c.req.param()
  const db = createDb(c.env)

  const sub = await getSubscriptionByTenantSlug(db, slug)
  if (!sub) {
    return c.json({ error: 'not_found', message: `No subscription found for tenant '${slug}'` }, 404)
  }

  return c.json(sub)
})

// ---------------------------------------------------------------------------
// PATCH /api/admin/tenants/:slug/subscription
// ---------------------------------------------------------------------------

const patchBodySchema = z.object({
  tier: z.enum(['freelancer', 'business', 'enterprise', 'white_label']),
  status: z.enum(['active', 'trialing', 'past_due', 'canceled']),
  note: z.string().optional(),
})

adminSubscriptionRoute.patch('/:slug/subscription', async (c) => {
  const session = c.get('session') as AdminSessionPayload
  const { slug } = c.req.param()

  const body = await c.req.json().catch(() => null)
  const parsed = patchBodySchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'invalid_body', issues: parsed.error.issues }, 400)
  }
  const { tier, status, note } = parsed.data

  const db = createDb(c.env)

  // Resolve the tenant id from slug
  const tenantId = await getTenantIdBySlug(db, slug)
  if (!tenantId) {
    return c.json({ error: 'not_found', message: `Tenant '${slug}' not found` }, 404)
  }

  // Upsert subscription with adapter='manual'
  const updated = await upsertAdminSubscription(db, tenantId, { tier, status })

  // Sync the tier to tenants.tier
  await syncTierToTenant(db, tenantId, tier as TenantTier)

  // Audit log: actor = admin user id
  await logAdminSubscriptionOverride(db, {
    tenantId,
    adminId: session.sub,
    subscriptionId: updated.id,
    tier,
    status,
    note,
  })

  return c.json(updated)
})
