/**
 * Account settings routes — settings-module (wave-9 leaf 4).
 * Mounted at /api/settings/account.
 *
 * GET  / → { name, slug, timezone, logo_url }
 * PATCH / → update name / timezone / logo_url
 *
 * Guarded by authMiddleware + settings:write permission on PATCH.
 * PATCH writes an audit log row in the same transaction (via query helper).
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import {
  createDb,
  getTenantAccountSettings,
  updateTenantAccountSettings,
} from '@zync/db/queries'
import { isValidTimezone } from '@zync/types'

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

const patchAccountSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  timezone: z.string().refine(isValidTimezone, { message: 'Invalid IANA timezone' }).optional(),
  logo_url: z.string().url().nullable().optional(),
})

// ── Router ────────────────────────────────────────────────────────────────────

export const accountSettingsRoute = new Hono<AppEnv>()

accountSettingsRoute.use('*', authMiddleware)

// GET /api/settings/account
accountSettingsRoute.get('/', 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') ?? createDb(c.env)
  const settings = await getTenantAccountSettings(db, session.tid)
  if (!settings) {
    return c.json({ error: 'Tenant not found' }, 404)
  }

  return c.json(
    {
      name: settings.name,
      slug: settings.slug,
      timezone: settings.timezone,
      logo_url: settings.logoUrl,
    },
    200,
  )
})

// PATCH /api/settings/account
accountSettingsRoute.patch(
  '/',
  requirePermission('settings:write'),
  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 = patchAccountSchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const { name, timezone, logo_url } = parsed.data
    if (name === undefined && timezone === undefined && logo_url === undefined) {
      return c.json({ error: 'No updatable field supplied' }, 422)
    }

    const db = c.get('db') ?? createDb(c.env)
    const ip = c.req.header('CF-Connecting-IP') ?? null
    const requestId = c.req.header('X-Request-Id') ?? null

    await updateTenantAccountSettings(
      db,
      session.tid,
      session.sub,
      {
        ...(name !== undefined ? { name } : {}),
        ...(timezone !== undefined ? { timezone } : {}),
        ...(logo_url !== undefined ? { logoUrl: logo_url } : {}),
      },
      { actorIp: ip, requestId },
    )

    const updated = await getTenantAccountSettings(db, session.tid)
    return c.json(
      {
        name: updated?.name ?? '',
        slug: updated?.slug ?? '',
        timezone: updated?.timezone ?? 'Asia/Jerusalem',
        logo_url: updated?.logoUrl ?? null,
      },
      200,
    )
  },
)
