import { describe, expect, it } from "vitest";
import { parseCommandDoc, errorCodeToClassName } from "./parse-command-doc";

describe("parseCommandDoc", () => {
  it("extracts error codes and descriptions from Error Scenarios section", () => {
    const markdown = `# CreateItem

## Overview

Creates a new item.

## Business Rules

- SKU must be unique

## Process Flow

\`\`\`mermaid
flowchart TD
    A[Start] --> B[End]
\`\`\`

## External Dependencies

- [primitives::Unit](../../../primitives/docs/models/Unit.md) - Validates UoM

## Error Scenarios

- **DUPLICATE_SKU**: An item with the same SKU already exists
- **DUPLICATE_BARCODE**: An item with the same barcode already exists
- **UNIT_NOT_FOUND**: Referenced unit does not exist or is inactive
`;

    const result = parseCommandDoc("CreateItem", markdown);

    expect(result.commandName).toBe("createItem");
    expect(result.errors).toEqual([
      { code: "DUPLICATE_SKU", description: "An item with the same SKU already exists" },
      { code: "DUPLICATE_BARCODE", description: "An item with the same barcode already exists" },
      { code: "UNIT_NOT_FOUND", description: "Referenced unit does not exist or is inactive" },
    ]);
    expect(result.externalDependencies).toEqual([{ module: "primitives", entity: "Unit" }]);
  });

  it("handles command doc with no external dependencies", () => {
    const markdown = `# CreateUser

## Overview

Creates a new user.

## Business Rules

- Email must be unique

## Process Flow

\`\`\`mermaid
flowchart TD
    A[Start] --> B[End]
\`\`\`

## External Dependencies

- None

## Error Scenarios

- **USER_ALREADY_EXISTS**: User with this email already exists
- **INVALID_EMAIL**: Invalid email format
`;

    const result = parseCommandDoc("CreateUser", markdown);

    expect(result.commandName).toBe("createUser");
    expect(result.externalDependencies).toEqual([]);
    expect(result.errors).toHaveLength(2);
  });

  it("handles command doc without External Dependencies section", () => {
    const markdown = `# ActivateItem

## Overview

Activates a draft item.

## Business Rules

- Item must be in DRAFT status

## Process Flow

\`\`\`mermaid
flowchart TD
    A[Start] --> B[End]
\`\`\`

## Error Scenarios

- **ITEM_NOT_FOUND**: Item does not exist
- **INVALID_STATE_TRANSITION**: Item is not in a valid state for activation
`;

    const result = parseCommandDoc("ActivateItem", markdown);

    expect(result.commandName).toBe("activateItem");
    expect(result.externalDependencies).toEqual([]);
    expect(result.errors).toHaveLength(2);
  });

  it("extracts multiple external dependencies", () => {
    const markdown = `# CreateOrder

## Overview

Creates an order.

## Business Rules

- Must reference valid item and customer

## Process Flow

\`\`\`mermaid
flowchart TD
    A[Start] --> B[End]
\`\`\`

## External Dependencies

- [item-management::Item](../../../item-management/docs/models/Item.md) - Validates item
- [primitives::Currency](../../../primitives/docs/models/Currency.md) - Validates currency

## Error Scenarios

- **ITEM_NOT_FOUND**: Referenced item does not exist
`;

    const result = parseCommandDoc("CreateOrder", markdown);

    expect(result.externalDependencies).toEqual([
      { module: "item-management", entity: "Item" },
      { module: "primitives", entity: "Currency" },
    ]);
  });
});

describe("errorCodeToClassName", () => {
  it("converts UPPER_SNAKE_CASE to PascalCase with Error suffix", () => {
    expect(errorCodeToClassName("DUPLICATE_SKU")).toBe("DuplicateSkuError");
    expect(errorCodeToClassName("UNIT_NOT_FOUND")).toBe("UnitNotFoundError");
    expect(errorCodeToClassName("ITEM_NOT_FOUND")).toBe("ItemNotFoundError");
    expect(errorCodeToClassName("USER_ALREADY_EXISTS")).toBe("UserAlreadyExistsError");
  });

  it("handles single word codes", () => {
    expect(errorCodeToClassName("UNAUTHORIZED")).toBe("UnauthorizedError");
  });
});
