import { NextResponse } from 'next/server';
import { z } from 'zod';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { errorResponse, NotFoundError } from '@/lib/errors';
import { createPortalUser, resendActivation } from '@/lib/services/portal-auth.service';
import { db } from '@/lib/db';
import { eq } from 'drizzle-orm';
import { portalUsers } from '@/lib/db/schema/portal';

const inviteSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(200).optional(),
});

/**
 * POST /api/v1/clients/:id/portal-user
 *
 * Admin creates a portal account for a client and triggers the activation
 * email. Idempotent in spirit: if a portal user already exists for the
 * email, returns 409 - the admin can resend the activation via
 * ?action=resend.
 */
export const POST = withAuth(
  withPermission('clients', 'edit', async (req, ctx, params) => {
    try {
      const url = new URL(req.url);
      const action = url.searchParams.get('action');

      if (action === 'resend') {
        // Body is optional in resend mode; the portal user id is the path id
        // in this case (not the client id). Looking up by client+email so
        // admins don't have to track portal-user ids.
        const body = await parseBody(req, inviteSchema);
        const existing = await db.query.portalUsers.findFirst({
          where: eq(portalUsers.email, body.email.toLowerCase().trim()),
        });
        if (!existing) throw new NotFoundError('portal user');
        await resendActivation(existing.id, ctx.portId);
        return new NextResponse(null, { status: 204 });
      }

      const body = await parseBody(req, inviteSchema);
      const result = await createPortalUser({
        clientId: params.id!,
        portId: ctx.portId,
        email: body.email,
        name: body.name,
        createdBy: ctx.userId,
      });
      return NextResponse.json({ data: result }, { status: 201 });
    } catch (err) {
      return errorResponse(err);
    }
  }),
);
