import Foundation
import SwiftData
import Testing
@testable import Workouts

/// Exercises the exact fetches `ExerciseLibraryDetailView` builds its machine-settings
/// card and progression-chart gate from, against an in-memory store — locking the
/// predicate shapes to the cache schema.
@MainActor
struct ExerciseLibraryQueryTests {

    private func makeContext() throws -> ModelContext {
        let schema = Schema([Routine.self, Exercise.self, Workout.self, WorkoutLog.self])
        // cloudKitDatabase: .none matches WorkoutsModelContainer — see SeedLibraryTests.
        let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true, cloudKitDatabase: .none)
        let container = try ModelContainer(for: schema, configurations: [config])
        return ModelContext(container)
    }

    @Test func machineSettingsFetchFindsRecordedSettings() throws {
        let context = try makeContext()
        // PINNED: routine documents live under the on-disk "Splits/" directory.
        let routine = Routine(id: "S1", name: "Upper Body", color: "indigo",
                          systemImage: "dumbbell.fill", order: 0,
                          createdAt: .now, updatedAt: .now, jsonRelativePath: "Splits/S1.json")
        let exercise = Exercise(id: "E1", name: "Chest Press", order: 0, sets: 3, reps: 10,
                                weight: 100, loadType: LoadType.weight.rawValue,
                                durationTotalSeconds: 0,
                                machineSettings: [MachineSetting(name: "Seat Height", value: "4")])
        exercise.routine = routine
        context.insert(routine)
        context.insert(exercise)
        try context.save()

        let name = "Chest Press"
        let fetched = try context.fetch(FetchDescriptor<Exercise>(
            predicate: #Predicate { $0.name == name }
        ))
        #expect(fetched.count == 1)
        #expect(fetched.first?.machineSettings == [MachineSetting(name: "Seat Height", value: "4")])
        #expect(fetched.first?.routine?.name == "Upper Body")
    }

    @Test func weightedLogFetchGatesChart() throws {
        let context = try makeContext()
        let workout = Workout(id: "W1", routineID: nil, routineName: "Upper Body",
                              start: .now, end: .now, statusRaw: WorkoutStatus.completed.rawValue,
                              createdAt: .now, updatedAt: .now,
                              jsonRelativePath: "Workouts/2026/07/W1.json")
        let weighted = WorkoutLog(id: "L1", exerciseName: "Chest Press", order: 0, sets: 3,
                                  reps: 10, weight: 100, loadType: LoadType.weight.rawValue,
                                  durationTotalSeconds: 0, currentStateIndex: 3,
                                  statusRaw: WorkoutStatus.completed.rawValue, notes: nil, date: .now)
        let bodyweight = WorkoutLog(id: "L2", exerciseName: "Plank", order: 1, sets: 3,
                                    reps: 0, weight: 0, loadType: LoadType.duration.rawValue,
                                    durationTotalSeconds: 60, currentStateIndex: 3,
                                    statusRaw: WorkoutStatus.completed.rawValue, notes: nil, date: .now)
        weighted.workout = workout
        bodyweight.workout = workout
        context.insert(workout)
        context.insert(weighted)
        context.insert(bodyweight)
        try context.save()

        let completedRaw = WorkoutStatus.completed.rawValue

        let chestPress = "Chest Press"
        let chestLogs = try context.fetch(FetchDescriptor<WorkoutLog>(
            predicate: #Predicate { $0.exerciseName == chestPress && $0.statusRaw == completedRaw && $0.weight > 0 }
        ))
        #expect(chestLogs.count == 1)

        let plank = "Plank"
        let plankLogs = try context.fetch(FetchDescriptor<WorkoutLog>(
            predicate: #Predicate { $0.exerciseName == plank && $0.statusRaw == completedRaw && $0.weight > 0 }
        ))
        #expect(plankLogs.isEmpty)
    }
}
