import { NextResponse } from 'next/server';
import { SDKError } from '@vercel/sdk/models/sdkerror';
import { SDKValidationError } from '@vercel/sdk/models/sdkvalidationerror';
import { prismaError } from 'prisma-better-errors';
import { Prisma } from '@prisma/client';

export function createResponse(status: number, message: string, data: Record<string, unknown> = {}) {
  return NextResponse.json({ message, ...data }, { status });
}

export function createRedirectResponse(path: string, params: Record<string, string>) {
  const url = new URL(`${process.env.NEXT_PUBLIC_FRONTEND_URL}${path}`);
  Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value));
  return NextResponse.redirect(url.toString());
}

export function handleApiError(
  error:
    | SDKError
    | Prisma.PrismaClientKnownRequestError
    | Prisma.PrismaClientValidationError
    | SDKValidationError
    | Error
    | null
    | undefined
) {
  if (error instanceof Prisma.PrismaClientKnownRequestError) {
    const err = new prismaError(error);
    if (error.code === 'P2002') {
      const fields = (error.meta?.target as string[]) || [];

      if (fields.includes('userId')) {
        if (fields.includes('title')) {
          return createResponse(err.statusCode, 'You already have a project with this title.');
        }
      }

      if (fields.includes('ownerId')) {
        if (fields.includes('title')) {
          return createResponse(err.statusCode, 'You already have a portfolio with this name.');
        }
      }

      const messages = fields.map((field) => {
        switch (field) {
          case 'email':
            return 'Email is already taken.';
          case 'username':
            return 'Username is already taken.';
          default:
            return `This ${field} is already in use.`;
        }
      });

      const message = messages.length > 0 ? messages.join(' ') : 'A duplicate entry was found.';

      return createResponse(err.statusCode, message);
    }
    return createResponse(err.statusCode, err.message);
  }

  if (error instanceof Prisma.PrismaClientValidationError) {
    return createResponse(400, 'Invalid request', {
      error: error.message,
    });
  }

  if (error instanceof SDKValidationError) {
    return createResponse(400, 'Invalid request', {
      error: error.message,
    });
  }

  if (error instanceof SDKError) {
    return createResponse(error.statusCode, error.message);
  }

  console.error('Unhandled error:', error);
  return createResponse(500, 'An unknown error occurred');
}

export const PAGE_SIZE = 25;
