import XCTest
@testable import MealMood

final class AutocompleteEngineTests: XCTestCase {

    func testValidateDropRejectsConsecutiveTag() {
        let tag = Tag(
            name: "Carne",
            nameEN: "Meat",
            color: "#E74C3C",
            maxPerWeek: nil,
            noConsecutive: true,
            noDuplicateInDay: false
        )

        let dishA = Dish(name: "Pollo", tagIds: [tag.id])
        let dishB = Dish(name: "Ternera", tagIds: [tag.id])

        let plan = WeekPlan(weekStartDate: Date().startOfWeek())
        let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: dishA.id)
        let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil)
        plan.slots = [mondayDinner, tuesdayDinner]

        let isValid = AutocompleteEngine.validateDrop(
            dish: dishB,
            slot: tuesdayDinner,
            plan: plan,
            allTags: [tag],
            allDishes: [dishA, dishB]
        )

        XCTAssertFalse(isValid)
    }

    func testAutocompleteLeavesSlotEmptyWhenMaxPerWeekReached() {
        let tag = Tag(
            name: "Pescado",
            nameEN: "Fish",
            color: "#3498DB",
            maxPerWeek: 1,
            noConsecutive: false,
            noDuplicateInDay: false
        )

        let fishDish = Dish(name: "Salmon", tagIds: [tag.id])
        let plan = WeekPlan(weekStartDate: Date().startOfWeek())

        let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: fishDish.id)
        let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil)
        plan.slots = [mondayDinner, tuesdayDinner]

        let result = AutocompleteEngine.autocomplete(
            emptySlots: [tuesdayDinner],
            currentPlan: plan,
            allDishes: [fishDish],
            allTags: [tag]
        )

        XCTAssertEqual(result.unfilledCount, 1)
        XCTAssertNil(tuesdayDinner.dishId)
    }

    func testDishStableSortRemainsConsistentAfterDeletion() {
        let base = Date()
        let oldest = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000001")!, name: "Old", createdAt: base.addingTimeInterval(-60))
        let newest = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000002")!, name: "New", createdAt: base)
        let middle = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000003")!, name: "Middle", createdAt: base.addingTimeInterval(-30))

        let initial = Dish.stableSortedForDisplay([oldest, newest, middle]).map(\.id)
        XCTAssertEqual(initial, [newest.id, middle.id, oldest.id])

        let afterDeletion = Dish.stableSortedForDisplay([newest, oldest]).map(\.id)
        XCTAssertEqual(afterDeletion, [newest.id, oldest.id])
    }

    func testPreferredDuplicateSlotKeepsAssignedDish() {
        let duplicateWithDish = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: UUID())
        let duplicateWithoutDish = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: nil)

        let preferred = MealSlot.preferredForDuplicateResolution([duplicateWithoutDish, duplicateWithDish])
        XCTAssertEqual(preferred.id, duplicateWithDish.id)
    }
}
