import { NextResponse } from 'next/server';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { errorResponse, ValidationError } from '@/lib/errors';
import { uploadFile } from '@/lib/services/files';
import { uploadFileSchema } from '@/lib/validators/files';

export const POST = withAuth(
  withPermission('files', 'upload', async (req, ctx) => {
    try {
      const formData = await req.formData();
      const file = formData.get('file') as File | null;

      if (!file) {
        throw new ValidationError('No file provided');
      }

      const buffer = Buffer.from(await file.arrayBuffer());

      const folderIdRaw = formData.get('folderId') as string | undefined;
      const metadata = uploadFileSchema.parse({
        filename: (formData.get('filename') as string | null) ?? file.name,
        clientId: formData.get('clientId') as string | undefined,
        yachtId: formData.get('yachtId') as string | undefined,
        companyId: formData.get('companyId') as string | undefined,
        category: formData.get('category') as string | undefined,
        entityType: formData.get('entityType') as string | undefined,
        entityId: formData.get('entityId') as string | undefined,
        // Hub uploads pass the current folderId so the file lands inside
        // the user's currently-selected folder. Empty string ⇒ root (null).
        folderId: folderIdRaw && folderIdRaw.length > 0 ? folderIdRaw : undefined,
      });

      const result = await uploadFile(
        ctx.portId,
        ctx.portSlug,
        {
          buffer,
          originalName: file.name,
          mimeType: file.type,
          size: file.size,
        },
        metadata,
        {
          userId: ctx.userId,
          portId: ctx.portId,
          ipAddress: ctx.ipAddress,
          userAgent: ctx.userAgent,
        },
      );

      return NextResponse.json({ data: result }, { status: 201 });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
