import type { Request, Response, NextFunction } from 'express';

import { DISK_FULL_MESSAGE, isDiskFullError } from '../lib/uploadErrors';



export class AppError extends Error {

  constructor(

    public statusCode: number,

    message: string,

  ) {

    super(message);

    this.name = 'AppError';

  }

}



export function errorHandler(

  err: Error,

  _req: Request,

  res: Response,

  _next: NextFunction,

): void {

  if (err instanceof AppError) {

    res.status(err.statusCode).json({ message: err.message });

    return;

  }



  if (isDiskFullError(err)) {

    res.status(507).json({ message: DISK_FULL_MESSAGE });

    return;

  }



  const bodyErr = err as Error & { type?: string; statusCode?: number };

  if (bodyErr.type === 'entity.parse.failed' || bodyErr.statusCode === 400) {

    res.status(400).json({ message: '요청 형식이 올바르지 않습니다.' });

    return;

  }



  console.error('[Error]', err);



  const prismaCode = (err as { code?: string }).code;

  if (prismaCode === 'P2022') {

    res.status(500).json({ message: 'DB 스키마가 최신이 아닙니다. 서버시작.bat 으로 다시 시작해 주세요.' });

    return;

  }

  if (prismaCode === 'P2021') {

    res.status(500).json({ message: 'DB 테이블이 없습니다. 서버시작.bat 으로 db:sync 후 다시 시도해 주세요.' });

    return;

  }



  res.status(500).json({ message: '서버 오류가 발생했습니다.' });

}

