import Foundation
import SwiftData

/// Builds the bundled machine-based starter routine (Upper Body / Core / Lower
/// Body). Written on demand (never auto-seeded) through the SyncEngine — an empty
/// cache at launch can't be told apart from an iCloud library that simply hasn't
/// downloaded yet.
enum SplitSeeder {
    /// One starter exercise: name plus its default starting weight (lbs).
    private struct SeedExercise {
        let name: String
        let weight: Int
    }

    /// One starter split: visual theme plus its ordered exercises.
    private struct SeedSplit {
        let name: String
        let color: String
        let icon: String
        let exercises: [SeedExercise]
    }

    /// Sets/reps shared by every starter exercise.
    private static let defaultSets = 4
    private static let defaultReps = 10

    /// Starter splits in display order, with sensible machine starting weights.
    /// Users adjust weights from the exercise screen.
    private static let starterSplits: [SeedSplit] = [
        SeedSplit(name: "Upper Body", color: "blue", icon: "figure.strengthtraining.traditional", exercises: [
            SeedExercise(name: "Lat Pull Down", weight: 110),
            SeedExercise(name: "Tricep Press", weight: 100),
            SeedExercise(name: "Chest Press", weight: 40),
            SeedExercise(name: "Seated Row", weight: 90),
        ]),
        SeedSplit(name: "Core", color: "orange", icon: "figure.core.training", exercises: [
            SeedExercise(name: "Abdominal", weight: 0),
            SeedExercise(name: "Rotary", weight: 0),
        ]),
        SeedSplit(name: "Lower Body", color: "green", icon: "figure.run", exercises: [
            SeedExercise(name: "Abductor", weight: 140),
            SeedExercise(name: "Adductor", weight: 140),
            SeedExercise(name: "Leg Press", weight: 160),
            SeedExercise(name: "Leg Curl", weight: 70),
        ]),
    ]

    /// Builds the default split documents (fresh ULIDs each call).
    static func defaultSplitDocuments() -> [SplitDocument] {
        starterSplits.enumerated().map { order, split in
            let exercises = split.exercises.enumerated().map { idx, item in
                ExerciseDocument(
                    id: ULID.make(), name: item.name, order: idx,
                    sets: defaultSets, reps: defaultReps, weight: item.weight,
                    loadType: LoadType.weight.rawValue,
                    durationSeconds: 0, weightLastUpdated: nil, weightReminderWeeks: 2
                )
            }
            return SplitDocument(
                schemaVersion: SplitDocument.currentSchema, id: ULID.make(),
                name: split.name, color: split.color, systemImage: split.icon, order: order,
                createdAt: Date(), updatedAt: Date(), exercises: exercises
            )
        }
    }

    /// Writes any starter splits whose name doesn't already exist, appended after
    /// existing splits. Idempotent against double-taps / partial prior seeds.
    @MainActor
    static func seedDefaults(into context: ModelContext, using sync: SyncEngine) async {
        let existing = (try? context.fetch(FetchDescriptor<Split>())) ?? []
        let existingNames = Set(existing.map(\.name))
        let base = existing.count

        let fresh = defaultSplitDocuments().filter { !existingNames.contains($0.name) }
        for (offset, var doc) in fresh.enumerated() {
            doc.order = base + offset
            await sync.save(split: doc)
        }
    }
}
