import { describe, it, expect } from 'vitest';
import {
  AppError,
  NotFoundError,
  UnauthorizedError,
  ForbiddenError,
  ConflictError,
  BadRequestError,
} from '../../src/common/errors.js';

describe(AppError.name, () => {
  it('sets statusCode, error, message, and details', () => {
    const details = { field: ['required'] };
    const err = new AppError(422, 'Unprocessable', 'Bad input', details);

    expect(err).toBeInstanceOf(Error);
    expect(err).toBeInstanceOf(AppError);
    expect(err.statusCode).toBe(422);
    expect(err.error).toBe('Unprocessable');
    expect(err.message).toBe('Bad input');
    expect(err.details).toEqual(details);
  });

  it('works without details', () => {
    const err = new AppError(500, 'Internal', 'Oops');
    expect(err.details).toBeUndefined();
  });
});

describe(NotFoundError.name, () => {
  it('defaults to 404 with standard message', () => {
    const err = new NotFoundError();
    expect(err.statusCode).toBe(404);
    expect(err.error).toBe('Not Found');
    expect(err.message).toBe('Resource not found');
  });

  it('accepts custom message', () => {
    const err = new NotFoundError('User not found');
    expect(err.message).toBe('User not found');
  });
});

describe(UnauthorizedError.name, () => {
  it('defaults to 401', () => {
    const err = new UnauthorizedError();
    expect(err.statusCode).toBe(401);
    expect(err.error).toBe('Unauthorized');
    expect(err.message).toBe('Unauthorized');
  });
});

describe(ForbiddenError.name, () => {
  it('defaults to 403', () => {
    const err = new ForbiddenError();
    expect(err.statusCode).toBe(403);
    expect(err.error).toBe('Forbidden');
    expect(err.message).toBe('Forbidden');
  });
});

describe(ConflictError.name, () => {
  it('defaults to 409', () => {
    const err = new ConflictError();
    expect(err.statusCode).toBe(409);
    expect(err.error).toBe('Conflict');
    expect(err.message).toBe('Conflict');
  });
});

describe(BadRequestError.name, () => {
  it('defaults to 400', () => {
    const err = new BadRequestError();
    expect(err.statusCode).toBe(400);
    expect(err.error).toBe('Bad Request');
    expect(err.message).toBe('Bad Request');
  });

  it('accepts message and details', () => {
    const details = { name: ['too short'] };
    const err = new BadRequestError('Invalid input', details);
    expect(err.message).toBe('Invalid input');
    expect(err.details).toEqual(details);
  });
});
