//
//  CreateWorkout.swift
//  Werkout_ios
//
//  Created by Trey Tartt on 6/15/23.
//

import Foundation
import SwiftUI
import Combine
import AVKit

struct AddExerciseView: View {
    enum CreateWorkoutItemPickerViewType {
        case muscles
        case equipment
    }
    
    @State var selectedMuscles = [Muscle]()
    @State var selectedEquipment = [Equipment]()
    @State var filteredExercises = [Exercise]()
        
    @StateObject var bridgeModule = BridgeModule.shared
    @Environment(\.dismiss) var dismiss
    var selectedExercise: ((Exercise) -> Void)
    @State var createWorkoutItemPickerViewModel: CreateWorkoutItemPickerViewModel?
    @State var createWorkoutItemPickerViewType: CreateWorkoutItemPickerViewType?
    @State var searchString: String = ""
    @State var videoExercise: Exercise? {
        didSet {
            if let viddd = self.videoExercise?.videoURL,
               let url = URL(string: BaseURLs.currentBaseURL + viddd) {
                self.avPlayer = AVPlayer(url: url)
            }
        }
    }
    @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!)
    
    var body: some View {
        VStack {
            AllExerciseList()
                .padding(.top)
            
            TextField("Filter", text: $searchString)
                .padding()
                        
            HStack {
                muscleView()
                    .frame(maxWidth: .infinity)
                
                Divider()
                
                equipmentView()
                    .frame(maxWidth: .infinity)
            }
            .padding(.top)
            .frame(height: 44)
        }
        .onAppear{
            if #function.hasPrefix("__preview") {
                DataStore.shared.setupFakeData()
            }
            guard let exercises = DataStore.shared.allExercise,
                  let muscles = DataStore.shared.allMuscles,
                  let equipment = DataStore.shared.allEquipment else {
                return
            }
            selectedMuscles = muscles
            selectedEquipment = equipment
            filteredExercises = exercises
        }
        .sheet(item: $videoExercise) { exercise in
            PlayerView(player: $avPlayer)
                .onAppear{
                    avPlayer.play()
                }
        }
        .sheet(item: $createWorkoutItemPickerViewModel) { item in
            CreateWorkoutItemPickerView(viewModel: item, completed: { selectedids in
                if let viewType = createWorkoutItemPickerViewType {
                    switch viewType {
                    case .muscles:
                        if let muscles = DataStore.shared.allMuscles {
                            selectedMuscles.removeAll()
                            for id in selectedids {
                                if let muscle = muscles.first(where: {
                                    $0.id == id
                                }) {
                                    selectedMuscles.append(muscle)
                                }
                            }
                        }
                    case .equipment:
                        if let equipment = DataStore.shared.allEquipment {
                            selectedEquipment.removeAll()
                            for id in selectedids {
                                if let equipment = equipment.first(where: {
                                    $0.id == id
                                }) {
                                    selectedEquipment.append(equipment)
                                }
                            }
                        }
                    }
                }

                filterExercises()
            })
        }
    }
    
    func filterExercises() {
        if selectedMuscles.count == 0 {
            filteredExercises = [Exercise]()
            return
        }

        if selectedEquipment.count == 0 {
            filteredExercises = [Exercise]()
            return
        }
        
        guard let exercises = DataStore.shared.allExercise,
              let muscles = DataStore.shared.allMuscles,
              let equipment = DataStore.shared.allEquipment else {
            filteredExercises = [Exercise]()
            return
        }
        
        filteredExercises = exercises.filter({ exercise in
            var hasCorrectMuscles = false
            if selectedMuscles.count == muscles.count {
                hasCorrectMuscles = true
            } else {
                let exerciseMuscleIds = exercise.muscles.map({ $0.id })
                let selctedMuscleIds = selectedMuscles.map({ $0.id })
                // if one items match
                if exerciseMuscleIds.contains(where: selctedMuscleIds.contains) {
                // if all items match
//                if exerciseMuscleIds.contains(selctedMuscleIds) {
                    hasCorrectMuscles = true
                }
            }
            
            var hasCorrectEquipment = false
            if selectedEquipment.count == equipment.count {
                hasCorrectEquipment = true
            } else {
                let exerciseEquipmentIds = exercise.equipment.map({ $0.id })
                let selctedEquipmentIds = selectedEquipment.map({ $0.id })
                // if one items match
                if exerciseEquipmentIds.contains(where: selctedEquipmentIds.contains) {
                // if all items match
//                if exerciseEquipmentIds.contains(selctedEquipmentIds) {
                    hasCorrectEquipment = true
                }
            }
            
            return hasCorrectMuscles && hasCorrectEquipment
        })
    }
        
    func muscleView() -> some View {
        VStack {
            if let _ = DataStore.shared.allMuscles {
                Text("Select Muscles")
                    .foregroundColor(.cyan)
                Text("\(selectedMuscles.count) Selected")
            }
        }
        .onTapGesture {
            if let muscles = DataStore.shared.allMuscles {
                var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]()
                muscles.forEach({
                    let model = CreateWorkoutItemPickerModel(id: $0.id, name: $0.name.lowercased())
                    createWorkoutItemPickerModels.append(model)
                })
                createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: {
                    $0.name < $1.name
                })
                let selectedIds = selectedMuscles.map { $0.id }
                createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds)
                createWorkoutItemPickerViewType = .muscles
            }
        }
    }
    
    func equipmentView() -> some View {
        VStack {
            if let _ = DataStore.shared.allEquipment {
                Text("Select Equipment")
                    .foregroundColor(.cyan)
                Text("\(selectedEquipment.count) Selected")
            }
        }
        .onTapGesture {
            if let equipment = DataStore.shared.allEquipment {
                var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]()
                equipment.forEach({
                    let model = CreateWorkoutItemPickerModel(id: $0.id,
                                                             name: $0.name.lowercased())
                    createWorkoutItemPickerModels.append(model)
                })
                createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: {
                    $0.name < $1.name
                })
                let selectedIds = selectedEquipment.map { $0.id }
                createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds)
                createWorkoutItemPickerViewType = .equipment
            }
        }
    }
    
    func AllExerciseList() -> some View {
        List() {
            ForEach(filteredExercises.indices, id: \.self) { i in
                let exercise = filteredExercises[i]
                if searchString.isEmpty || (exercise.name.lowercased().contains(searchString.lowercased()) || exercise.muscleGroups.lowercased().contains(searchString.lowercased())) {
                    HStack {
                        VStack {
                            Text(exercise.name)
                                .frame(maxWidth: .infinity, alignment: .leading)
                            
                            if !exercise.side.isEmpty {
                                Text(exercise.side)
                                    .font(.footnote)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                            
                            if !exercise.equipmentRequired.isEmpty {
                                Text(exercise.spacedEquipmentRequired)
                                    .font(.footnote)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                            
                            if !exercise.muscleGroups.isEmpty {
                                Text(exercise.spacedMuscleGroups)
                                    .font(.footnote)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                        }
                        .contentShape(Rectangle())
                        .onTapGesture {
                            selectedExercise(exercise)
                            dismiss()
                        }
                        Button(action: {
                            videoExercise = exercise
                        }) {
                            ZStack {
                                Circle()
                                    .fill(.blue)
                                    .frame(width: 33, height: 33)
                                Image(systemName: "video.fill")
                                    .frame(width: 33, height: 33)
                                    .foregroundColor(.white )
                            }
                        }
                        .frame(width: 33, height: 33)
                    }
                }
            }
        }
    }
}

struct AddExerciseView_Previews: PreviewProvider {
    static var previews: some View {
        AddExerciseView(selectedExercise: { _ in })
    }
}
