import { NextResponse } from 'next/server';
import { z } from 'zod';
import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';
import { initDatabase } from '@server/db/init';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, AuthedRequest } from '@server/middleware/withAuth';
import { ValidationError, ForbiddenError, NotFoundError } from '@server/errors';

const schema = z.object({
  email: z.string().email('Invalid email address'),
});

export const PATCH = withErrorHandler(
  withAuth(async (req: AuthedRequest, context: { params: Promise<Record<string, string>> }) => {
    await initDatabase();
    if (req.session.role !== 'superadmin') {
      throw new ForbiddenError();
    }

    const { userId } = await context.params;

    let body: unknown;
    try { body = await req.json(); } catch { throw new ValidationError('Request body must be valid JSON'); }

    const parsed = schema.safeParse(body);
    if (!parsed.success) {
      throw new ValidationError(parsed.error.issues[0]?.message ?? 'Invalid request');
    }
    const { email } = parsed.data;
    const normalized = email.toLowerCase().trim();

    const { rows: existing } = await db.execute(sql`
      SELECT 1 FROM users WHERE lower(email) = ${normalized} AND id != ${userId} LIMIT 1
    `);
    if ((existing as unknown[]).length > 0) {
      throw new ValidationError('This email is already in use');
    }

    const { rows: updated } = await db.execute(sql`
      UPDATE users SET email = ${normalized}, pending_email = NULL
      WHERE id = ${userId}
      RETURNING id
    `);
    if ((updated as unknown[]).length === 0) {
      throw new NotFoundError('User');
    }

    return NextResponse.json({ ok: true });
  })
);
