/**
 * Haptics utility tests
 */

import { describe, it, expect, beforeEach, vi } from "vitest";
import { haptic, haptics } from "./haptics";

describe("haptics utility", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Mock navigator.vibrate
    Object.defineProperty(global.navigator, "vibrate", {
      value: vi.fn(),
      configurable: true,
    });
  });

  describe("haptic function", () => {
    it("should trigger vibration with light style", () => {
      haptic("light");
      expect(navigator.vibrate).toHaveBeenCalledWith(10);
    });

    it("should trigger vibration with medium style", () => {
      haptic("medium");
      expect(navigator.vibrate).toHaveBeenCalledWith(20);
    });

    it("should trigger vibration with heavy style", () => {
      haptic("heavy");
      expect(navigator.vibrate).toHaveBeenCalledWith(40);
    });

    it("should trigger vibration with success style", () => {
      haptic("success");
      expect(navigator.vibrate).toHaveBeenCalledWith([10, 50, 10]);
    });

    it("should trigger vibration with warning style", () => {
      haptic("warning");
      expect(navigator.vibrate).toHaveBeenCalledWith([20, 100, 20, 100, 20]);
    });

    it("should trigger vibration with error style", () => {
      haptic("error");
      expect(navigator.vibrate).toHaveBeenCalledWith(50);
    });

    it("should use medium style by default", () => {
      haptic();
      expect(navigator.vibrate).toHaveBeenCalledWith(20);
    });

    it("should handle missing vibration API gracefully", () => {
      Object.defineProperty(global.navigator, "vibrate", {
        value: undefined,
        configurable: true,
      });

      expect(() => haptic()).not.toThrow();
    });

    it("should handle vibration errors gracefully", () => {
      Object.defineProperty(global.navigator, "vibrate", {
        value: vi.fn(() => {
          throw new Error("Vibration blocked");
        }),
        configurable: true,
      });

      expect(() => haptic()).not.toThrow();
    });
  });

  describe("haptics object", () => {
    it("should provide tap method", () => {
      haptics.tap();
      expect(navigator.vibrate).toHaveBeenCalledWith(10);
    });

    it("should provide select method", () => {
      haptics.select();
      expect(navigator.vibrate).toHaveBeenCalledWith(20);
    });

    it("should provide success method", () => {
      haptics.success();
      expect(navigator.vibrate).toHaveBeenCalledWith([10, 50, 10]);
    });

    it("should provide warning method", () => {
      haptics.warning();
      expect(navigator.vibrate).toHaveBeenCalledWith([20, 100, 20, 100, 20]);
    });

    it("should provide error method", () => {
      haptics.error();
      expect(navigator.vibrate).toHaveBeenCalledWith(50);
    });

    it("should provide impact method", () => {
      haptics.impact();
      expect(navigator.vibrate).toHaveBeenCalledWith(40);
    });
  });
});
