import { describe, it, expect } from "vitest";
import { HaloError, HttpError } from "../error";

describe("HaloError", () => {
  it("should create error with all properties", () => {
    const error = new HaloError("Test message", "TEST_CODE", 400, new Error("original"));

    expect(error.message).toBe("Test message");
    expect(error.code).toBe("TEST_CODE");
    expect(error.statusCode).toBe(400);
    expect(error.originalError).toBeInstanceOf(Error);
    expect(error.name).toBe("HaloError");
  });

  it("should create network error", () => {
    const error = HaloError.network(new Error("fetch failed"));

    expect(error.code).toBe("NETWORK_ERROR");
    expect(error.message).toBe("网络请求失败，请检查网络连接");
    expect(error.isNetworkError()).toBe(true);
    expect(error.isAuthError()).toBe(false);
  });

  it("should create unauthorized error", () => {
    const error = HaloError.unauthorized();

    expect(error.code).toBe("UNAUTHORIZED");
    expect(error.statusCode).toBe(401);
    expect(error.isAuthError()).toBe(true);
  });

  it("should create forbidden error", () => {
    const error = HaloError.forbidden();

    expect(error.code).toBe("FORBIDDEN");
    expect(error.statusCode).toBe(403);
    expect(error.isAuthError()).toBe(true);
  });

  it("should create notFound error", () => {
    const error = HaloError.notFound("Post");

    expect(error.code).toBe("NOT_FOUND");
    expect(error.statusCode).toBe(404);
    expect(error.message).toBe("Post 未找到");
    expect(error.isNotFound()).toBe(true);
  });

  it("should create server error", () => {
    const error = HaloError.serverError();

    expect(error.code).toBe("SERVER_ERROR");
    expect(error.statusCode).toBe(500);
  });

  it("should create validation error", () => {
    const error = HaloError.validationError("Invalid slug");

    expect(error.code).toBe("VALIDATION_ERROR");
    expect(error.message).toBe("Invalid slug");
  });

  it("should create unknown error from Error", () => {
    const original = new Error("Something went wrong");
    const error = HaloError.unknown(original);

    expect(error.code).toBe("UNKNOWN");
    expect(error.message).toBe("Something went wrong");
  });

  it("should create unknown error from non-Error", () => {
    const error = HaloError.unknown("string error");

    expect(error.code).toBe("UNKNOWN");
    expect(error.message).toBe("未知错误");
  });
});

describe("HttpError", () => {
  it("should create from status code 400", () => {
    const error = HttpError.fromStatus(400, { message: "bad request" });

    expect(error.statusCode).toBe(400);
    expect(error.message).toBe("请求参数错误");
    expect(error.name).toBe("HttpError");
  });

  it("should create from status code 401", () => {
    const error = HttpError.fromStatus(401);

    expect(error.statusCode).toBe(401);
    expect(error.message).toBe("认证失败");
  });

  it("should create from status code 404", () => {
    const error = HttpError.fromStatus(404);

    expect(error.statusCode).toBe(404);
    expect(error.message).toBe("资源不存在");
  });

  it("should create from status code 500", () => {
    const error = HttpError.fromStatus(500);

    expect(error.statusCode).toBe(500);
    expect(error.message).toBe("服务器内部错误");
  });

  it("should create from unknown status code", () => {
    const error = HttpError.fromStatus(418);

    expect(error.statusCode).toBe(418);
    expect(error.message).toBe("HTTP 错误 (418)");
  });
});