import { NextResponse } from 'next/server';
import { eq } from 'drizzle-orm';

import { withAuth } from '@/lib/api/helpers';
import { db } from '@/lib/db';
import { ports } from '@/lib/db/schema/ports';
import { userProfiles } from '@/lib/db/schema/users';
import { uploadFile } from '@/lib/services/files';
import { errorResponse, ValidationError } from '@/lib/errors';

const MAX_AVATAR_BYTES = 2 * 1024 * 1024;

/**
 * Profile-photo upload. Accepts a multipart `file` (cropped JPEG/PNG
 * from the ImageCropperDialog), persists it via the polymorphic files
 * table (so an S3↔filesystem swap carries it correctly), and writes
 * the file id into `user_profiles.avatar_file_id`.
 *
 * Files are scoped to the user's CURRENT port — the rep can't end up
 * with an avatar that's only visible from one port. (Avatars render
 * via the GET handler below, which presigns by id regardless of port.)
 */
export const POST = withAuth(async (req, ctx) => {
  try {
    const formData = await req.formData();
    const fileEntry = formData.get('file');
    if (!(fileEntry instanceof File)) {
      throw new ValidationError('Missing `file` part');
    }
    if (fileEntry.size === 0) {
      throw new ValidationError('Empty file');
    }
    if (fileEntry.size > MAX_AVATAR_BYTES) {
      throw new ValidationError('Avatar exceeds 2 MB');
    }

    // Resolve the port slug for the storage path. Super-admins without
    // an active port fall through to a synthetic 'global' bucket.
    const port = ctx.portId
      ? await db.query.ports.findFirst({ where: eq(ports.id, ctx.portId) })
      : null;
    const portSlug = port?.slug ?? 'global';
    const portId = ctx.portId || port?.id || '';
    if (!portId) throw new ValidationError('No active port');

    const buffer = Buffer.from(await fileEntry.arrayBuffer());
    const record = await uploadFile(
      portId,
      portSlug,
      {
        buffer,
        originalName: fileEntry.name || 'avatar.jpg',
        mimeType: fileEntry.type || 'image/jpeg',
        size: fileEntry.size,
      },
      {
        filename: `avatar-${ctx.userId}.jpg`,
        category: 'avatar',
        entityType: 'user',
        entityId: ctx.userId,
      },
      {
        userId: ctx.userId,
        portId,
        ipAddress: ctx.ipAddress,
        userAgent: ctx.userAgent,
      },
    );

    await db
      .update(userProfiles)
      .set({ avatarFileId: record.id, updatedAt: new Date() })
      .where(eq(userProfiles.userId, ctx.userId));

    return NextResponse.json({ data: { avatarFileId: record.id } });
  } catch (error) {
    return errorResponse(error);
  }
});
