//
// SplitDetailView.swift
// Workouts
//
// Created by rzen on 7/25/25 at 3:27 PM.
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//

import SwiftUI
import SwiftData

struct SplitDetailView: View {
    @Environment(SyncEngine.self) private var sync
    @Environment(\.dismiss) private var dismiss

    var split: Split

    @State private var showingExerciseAddSheet: Bool = false
    @State private var showingSplitEditSheet: Bool = false
    @State private var itemToEdit: Exercise? = nil
    @State private var itemToDelete: Exercise? = nil

    var body: some View {
        Form {
            Section(header: Text("What is a Split?")) {
                Text("A \"split\" is simply how you divide (or \"split up\") your weekly training across different days. Instead of working every muscle group every session, you assign certain muscle groups, movement patterns, or training emphases to specific days.")
                    .font(.caption)
            }

            Section(header: Text("Exercises")) {
                let sortedExercises = split.exercisesArray

                if !sortedExercises.isEmpty {
                    ForEach(sortedExercises) { item in
                        ListItem(
                            title: item.name,
                            subtitle: "\(item.sets) × \(item.reps) × \(item.weight) lbs"
                        )
                        .swipeActions {
                            Button {
                                itemToDelete = item
                            } label: {
                                Label("Delete", systemImage: "trash")
                            }
                            .tint(.red)
                            Button {
                                itemToEdit = item
                            } label: {
                                Label("Edit", systemImage: "pencil")
                            }
                            .tint(.indigo)
                        }
                    }
                    .onMove(perform: moveExercises)

                    Button {
                        showingExerciseAddSheet = true
                    } label: {
                        ListItem(systemName: "plus.circle", title: "Add Exercise")
                    }
                } else {
                    Text("No exercises added yet.")
                    Button(action: { showingExerciseAddSheet.toggle() }) {
                        ListItem(title: "Add Exercise")
                    }
                }
            }
        }
        .navigationTitle(split.name)
        .toolbar {
            ToolbarItem(placement: .primaryAction) {
                Button {
                    showingSplitEditSheet = true
                } label: {
                    Image(systemName: "pencil")
                }
            }
        }
        .sheet(isPresented: $showingExerciseAddSheet) {
            ExercisePickerView(onExerciseSelected: { exerciseNames in
                addExercises(names: exerciseNames)
            }, allowMultiSelect: true)
        }
        .sheet(isPresented: $showingSplitEditSheet) {
            SplitAddEditView(split: split) {
                dismiss()
            }
        }
        .sheet(item: $itemToEdit) { item in
            ExerciseAddEditView(exercise: item, split: split)
        }
        .confirmationDialog(
            "Delete Exercise?",
            isPresented: Binding(
                get: { itemToDelete != nil },
                set: { if !$0 { itemToDelete = nil } }
            ),
            titleVisibility: .visible,
            presenting: itemToDelete
        ) { item in
            Button("Delete", role: .destructive) {
                deleteExercise(item)
                itemToDelete = nil
            }
            Button("Cancel", role: .cancel) {
                itemToDelete = nil
            }
        } message: { item in
            Text("Remove \"\(item.name)\" from this split?")
        }
    }

    private func moveExercises(from source: IndexSet, to destination: Int) {
        var exercises = split.exercisesArray
        exercises.move(fromOffsets: source, toOffset: destination)
        var doc = SplitDocument(from: split)
        doc.exercises = exercises.enumerated().map { i, ex in
            var ed = ExerciseDocument(from: ex)
            ed.order = i
            return ed
        }
        doc.updatedAt = Date()
        Task { await sync.save(split: doc) }
    }

    private func addExercises(names: [String]) {
        var doc = SplitDocument(from: split)
        let existingNames = Set(doc.exercises.map { $0.name })
        let base = doc.exercises.count
        let newDocs = names
            .filter { !existingNames.contains($0) }
            .enumerated()
            .map { i, exName in
                ExerciseDocument(
                    id: ULID.make(), name: exName, order: base + i,
                    sets: 3, reps: 10, weight: 40,
                    loadType: LoadType.weight.rawValue,
                    durationSeconds: 0, weightLastUpdated: nil, weightReminderWeeks: 2
                )
            }
        doc.exercises.append(contentsOf: newDocs)
        doc.updatedAt = Date()
        Task { await sync.save(split: doc) }

        // If a single exercise was added, open the edit sheet once the cache refreshes.
        // We rely on the observer to populate it — no direct entity reference needed.
    }

    private func deleteExercise(_ exercise: Exercise) {
        var doc = SplitDocument(from: split)
        doc.exercises.removeAll { $0.id == exercise.id }
        // Re-number orders after removal
        for i in doc.exercises.indices {
            doc.exercises[i].order = i
        }
        doc.updatedAt = Date()
        Task { await sync.save(split: doc) }
    }
}
