import { describe, expect, it } from "@jest/globals"

import { getGroupedOpeningHours } from "./utils"

import type { IntlShape } from "react-intl"

import type { RestaurantOpeningHours } from "@/types/hotel"

// Mock IntlShape for testing
const mockIntl = {
  formatMessage: ({ id }: { id: string }) => {
    const messages: Record<string, string> = {
      Monday: "Monday",
      Tuesday: "Tuesday",
      Wednesday: "Wednesday",
      Thursday: "Thursday",
      Friday: "Friday",
      Saturday: "Saturday",
      Sunday: "Sunday",
      Closed: "Closed",
      "Always open": "Always open",
    }
    return messages[id] || id
  },
} as IntlShape

describe("getGroupedOpeningHours", () => {
  it("should group all days as closed", () => {
    const allDaysClosed: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 1,
      },
      tuesday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 2,
      },
      wednesday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 3,
      },
      thursday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 4,
      },
      friday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 5,
      },
      saturday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 6,
      },
      sunday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 7,
      },
    }
    const result = getGroupedOpeningHours(allDaysClosed, mockIntl)
    expect(result).toEqual(["Monday-Sunday: Closed"])
  })

  it("should group all days with same opening hours", () => {
    const allDaysSameHours: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 1,
      },
      tuesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 2,
      },
      wednesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
      thursday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 4,
      },
      friday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 5,
      },
      saturday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 6,
      },
      sunday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 7,
      },
    }
    const result = getGroupedOpeningHours(allDaysSameHours, mockIntl)
    expect(result).toEqual(["Monday-Sunday: 09:00-17:00"])
  })

  it("should handle mixed opening hours", () => {
    const mixedOpeningHours: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 1,
      },
      tuesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 2,
      },
      wednesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
      thursday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 4,
      },
      friday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 5,
      },
      saturday: {
        openingTime: "10:00",
        closingTime: "15:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 6,
      },
      sunday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 7,
      },
    }
    const result = getGroupedOpeningHours(mixedOpeningHours, mockIntl)
    expect(result).toEqual([
      "Monday-Friday: 09:00-17:00",
      "Saturday: 10:00-15:00",
      "Sunday: Closed",
    ])
  })

  it("should handle always open days", () => {
    const someAlwaysOpen: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        alwaysOpen: true,
        isClosed: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 1,
      },
      tuesday: {
        alwaysOpen: true,
        isClosed: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 2,
      },
      wednesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
      thursday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 4,
      },
      friday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 5,
      },
      saturday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 6,
      },
      sunday: {
        isClosed: true,
        alwaysOpen: false,
        openingTime: "",
        closingTime: "",
        sortOrder: 7,
      },
    }
    const result = getGroupedOpeningHours(someAlwaysOpen, mockIntl)
    expect(result).toEqual([
      "Monday-Tuesday: Always open",
      "Wednesday-Friday: 09:00-17:00",
      "Saturday-Sunday: Closed",
    ])
  })

  it("should handle missing days", () => {
    const missingDays: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 1,
      },
      wednesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
      friday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 5,
      },
    }
    const result = getGroupedOpeningHours(missingDays, mockIntl)
    expect(result).toEqual([
      "Monday: 09:00-17:00",
      "Wednesday: 09:00-17:00",
      "Friday: 09:00-17:00",
    ])
  })

  it("should not group non-consecutive days with same hours", () => {
    const nonConsecutiveSameHours: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 1,
      },
      tuesday: {
        openingTime: "10:00",
        closingTime: "18:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 2,
      },
      wednesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
    }
    const result = getGroupedOpeningHours(nonConsecutiveSameHours, mockIntl)
    expect(result).toEqual([
      "Monday: 09:00-17:00",
      "Tuesday: 10:00-18:00",
      "Wednesday: 09:00-17:00",
    ])
  })

  it("should handle nullable opening/closing times", () => {
    const nullableHours: RestaurantOpeningHours = {
      isActive: true,
      name: "Opening hours",
      monday: {
        openingTime: "",
        closingTime: "",
        isClosed: true,
        alwaysOpen: false,
        sortOrder: 1,
      },
      tuesday: {
        openingTime: "09:00",
        closingTime: "",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 2,
      },
      wednesday: {
        openingTime: "",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 3,
      },
    }
    const result = getGroupedOpeningHours(nullableHours, mockIntl)
    expect(result).toEqual([
      "Monday: Closed",
      // Tuesday and Wednesday won't appear in the result because they have empty string values
      // that don't match any of the conditions in the getGroupedOpeningHours function
    ])
  })

  it("should handle inactive restaurant hours", () => {
    const inactiveHours: RestaurantOpeningHours = {
      isActive: false,
      name: "Opening hours",
      monday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 1,
      },
      tuesday: {
        openingTime: "09:00",
        closingTime: "17:00",
        isClosed: false,
        alwaysOpen: false,
        sortOrder: 2,
      },
    }
    // Even though isActive is false, the function should still process the hours
    // as it doesn't check for the isActive flag
    const result = getGroupedOpeningHours(inactiveHours, mockIntl)
    expect(result).toEqual(["Monday-Tuesday: 09:00-17:00"])
  })
})
