/**
 * Unit Tests: Duration Mapping
 * Tests duration conversion from minutes to display format
 */

describe("Duration Mapping", () => {
  // Duration map from useBookingForm hook
  const durationMap: Record<number, string> = {
    30: "30min",
    60: "1hr",
    90: "1.5hr",
    120: "2hr",
  };

  describe("Standard Durations", () => {
    it('should map 30 minutes to "30min"', () => {
      expect(durationMap[30]).toBe("30min");
    });

    it('should map 60 minutes to "1hr"', () => {
      expect(durationMap[60]).toBe("1hr");
    });

    it('should map 90 minutes to "1.5hr"', () => {
      expect(durationMap[90]).toBe("1.5hr");
    });

    it('should map 120 minutes to "2hr"', () => {
      expect(durationMap[120]).toBe("2hr");
    });
  });

  describe("Duration Conversion Function", () => {
    // Helper function to convert duration (simulates backend logic)
    const convertDuration = (minutes: number): string => {
      return durationMap[minutes] || `${minutes}min`;
    };

    it("should convert all standard durations correctly", () => {
      expect(convertDuration(30)).toBe("30min");
      expect(convertDuration(60)).toBe("1hr");
      expect(convertDuration(90)).toBe("1.5hr");
      expect(convertDuration(120)).toBe("2hr");
    });

    it("should handle unknown durations gracefully", () => {
      expect(convertDuration(45)).toBe("45min");
      expect(convertDuration(15)).toBe("15min");
    });

    it("should return consistent format for all inputs", () => {
      const result30 = convertDuration(30);
      const result60 = convertDuration(60);

      expect(typeof result30).toBe("string");
      expect(typeof result60).toBe("string");
      expect(result30.length).toBeGreaterThan(0);
      expect(result60.length).toBeGreaterThan(0);
    });
  });

  describe("Display Format Validation", () => {
    it('should use "min" suffix for minutes', () => {
      expect(durationMap[30]).toMatch(/min$/);
    });

    it('should use "hr" suffix for hours', () => {
      expect(durationMap[60]).toMatch(/hr$/);
      expect(durationMap[90]).toMatch(/hr$/);
      expect(durationMap[120]).toMatch(/hr$/);
    });

    it("should use decimal notation for fractional hours", () => {
      expect(durationMap[90]).toContain("1.5");
    });

    it("should use whole number for complete hours", () => {
      expect(durationMap[60]).toBe("1hr");
      expect(durationMap[120]).toBe("2hr");
    });
  });

  describe("Backend API Format", () => {
    // Simulate API payload creation
    const createBookingPayload = (durationMinutes: number) => {
      return {
        duration: durationMap[durationMinutes] || `${durationMinutes}min`,
        durationMinutes,
      };
    };

    it("should create correct API payload for 30 minutes", () => {
      const payload = createBookingPayload(30);
      expect(payload.duration).toBe("30min");
      expect(payload.durationMinutes).toBe(30);
    });

    it("should create correct API payload for 60 minutes", () => {
      const payload = createBookingPayload(60);
      expect(payload.duration).toBe("1hr");
      expect(payload.durationMinutes).toBe(60);
    });

    it("should maintain both formats in payload", () => {
      const payload = createBookingPayload(90);
      expect(payload.duration).toBeDefined();
      expect(payload.durationMinutes).toBeDefined();
      expect(typeof payload.duration).toBe("string");
      expect(typeof payload.durationMinutes).toBe("number");
    });
  });

  describe("Reverse Mapping (Display to Minutes)", () => {
    // Helper to convert display format back to minutes
    const parseDuration = (displayFormat: string): number => {
      const reverseMap: Record<string, number> = {
        "30min": 30,
        "1hr": 60,
        "1.5hr": 90,
        "2hr": 120,
      };
      return reverseMap[displayFormat] || 0;
    };

    it('should convert "30min" back to 30', () => {
      expect(parseDuration("30min")).toBe(30);
    });

    it('should convert "1hr" back to 60', () => {
      expect(parseDuration("1hr")).toBe(60);
    });

    it('should convert "1.5hr" back to 90', () => {
      expect(parseDuration("1.5hr")).toBe(90);
    });

    it('should convert "2hr" back to 120', () => {
      expect(parseDuration("2hr")).toBe(120);
    });
  });

  describe("Duration Map Completeness", () => {
    it("should have entries for all supported durations", () => {
      expect(Object.keys(durationMap)).toHaveLength(4);
    });

    it("should have unique display values", () => {
      const values = Object.values(durationMap);
      const uniqueValues = new Set(values);
      expect(uniqueValues.size).toBe(values.length);
    });

    it("should have all keys as numbers", () => {
      Object.keys(durationMap).forEach((key) => {
        expect(typeof parseInt(key)).toBe("number");
        expect(isNaN(parseInt(key))).toBe(false);
      });
    });

    it("should have all values as strings", () => {
      Object.values(durationMap).forEach((value) => {
        expect(typeof value).toBe("string");
      });
    });
  });
});
