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, ValidationError } from '@/lib/errors';
import { minioClient } from '@/lib/minio';
import { env } from '@/lib/env';

const renameFolderSchema = z.object({
  newPath: z.string().min(1).max(500),
});

function sanitizeFolderPath(raw: string): string {
  return raw
    .replace(/\x00/g, '')
    .replace(/\.\.\//g, '')
    .replace(/^\/+/, '')
    .replace(/\/+/g, '/');
}

export const PATCH = withAuth(
  withPermission('files', 'edit', async (req, ctx, params) => {
    try {
      const pathSegments = params.path;
      const currentPath = Array.isArray(pathSegments)
        ? (pathSegments as string[]).join('/')
        : String(pathSegments);

      const body = await parseBody(req, renameFolderSchema);
      const safeCurrent = sanitizeFolderPath(currentPath);
      const safeNew = sanitizeFolderPath(body.newPath);

      if (!safeCurrent || !safeNew) {
        throw new ValidationError('Invalid folder path');
      }

      const oldKey = `${ctx.portSlug}/${safeCurrent}${safeCurrent.endsWith('/') ? '' : '/'}`;
      const newKey = `${ctx.portSlug}/${safeNew}${safeNew.endsWith('/') ? '' : '/'}`;

      // Create new marker, remove old
      await minioClient.putObject(env.MINIO_BUCKET, newKey, Buffer.alloc(0), 0, {
        'Content-Type': 'application/x-directory',
      });
      await minioClient.removeObject(env.MINIO_BUCKET, oldKey);

      return NextResponse.json({ data: { path: newKey } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);

export const DELETE = withAuth(
  withPermission('files', 'delete', async (req, ctx, params) => {
    try {
      const pathSegments = params.path;
      const currentPath = Array.isArray(pathSegments)
        ? (pathSegments as string[]).join('/')
        : String(pathSegments);

      const safePath = sanitizeFolderPath(currentPath);
      if (!safePath) {
        throw new ValidationError('Invalid folder path');
      }

      const folderKey = `${ctx.portSlug}/${safePath}${safePath.endsWith('/') ? '' : '/'}`;
      await minioClient.removeObject(env.MINIO_BUCKET, folderKey);

      return new NextResponse(null, { status: 204 });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
