import { describe, it, expect } from "vitest";
import { classifyTextBERT, extractFeatures, ruleEngine } from "./ml.engine";

describe("classifyTextBERT", () => {
  it("returns default classification", async () => {
    const result = await classifyTextBERT("Hello world");
    expect(result.isSpam).toBe(false);
    expect(result.confidence).toBe(1.0);
  });
});

describe("extractFeatures", () => {
  it("extracts area code from caller number", async () => {
    const features = await extractFeatures({ callerNumber: "+14155551234" });
    expect(features.areaCode).toBe("+14");
  });

  it("uses provided duration and timeOfDay", async () => {
    const features = await extractFeatures({ callerNumber: "+1234567890", duration: 120, timeOfDay: 9 });
    expect(features.duration).toBe(120);
    expect(features.timeOfDay).toBe(9);
  });
});

describe("ruleEngine", () => {
  it("matches phone number rule", async () => {
    const rules = [
      { id: "r1", ruleType: "phoneNumber", pattern: "+1234567890", action: "block" as const, priority: 10 },
    ];
    const result = await ruleEngine(rules, { phoneNumber: "+1234567890" });
    expect(result).not.toBeNull();
    expect(result!.action).toBe("block");
  });

  it("matches area code rule", async () => {
    const rules = [
      { id: "r2", ruleType: "areaCode" as const, pattern: "+12", action: "flag" as const, priority: 5 },
    ];
    const result = await ruleEngine(rules, { phoneNumber: "+1234567890" });
    expect(result).not.toBeNull();
    expect(result!.action).toBe("flag");
  });

  it("matches prefix rule", async () => {
    const rules = [
      { id: "r3", ruleType: "prefix" as const, pattern: "+12345", action: "challenge" as const, priority: 1 },
    ];
    const result = await ruleEngine(rules, { phoneNumber: "+1234567890" });
    expect(result).not.toBeNull();
    expect(result!.action).toBe("challenge");
  });

  it("matches pattern rule against text", async () => {
    const rules = [
      { id: "r4", ruleType: "pattern" as const, pattern: "free money", action: "block" as const, priority: 10 },
    ];
    const result = await ruleEngine(rules, { phoneNumber: "+1234567890", text: "Get free money now" });
    expect(result).not.toBeNull();
    expect(result!.action).toBe("block");
  });

  it("respects priority ordering", async () => {
    const rules = [
      { id: "r1", ruleType: "prefix" as const, pattern: "+12", action: "allow" as const, priority: 1 },
      { id: "r2", ruleType: "phoneNumber" as const, pattern: "+1234567890", action: "block" as const, priority: 10 },
    ];
    const result = await ruleEngine(rules, { phoneNumber: "+1234567890" });
    expect(result!.ruleId).toBe("r2");
  });

  it("returns null when no rules match", async () => {
    const result = await ruleEngine([], { phoneNumber: "+1234567890" });
    expect(result).toBeNull();
  });
});
