//
//  MainView.swift
//  Werkout_ios
//
//  Created by Trey Tartt on 6/14/23.
//

import SwiftUI
import AVKit

struct WorkoutDetailView: View {
    @StateObject var viewModel:  WorkoutDetailViewModel
    @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!)
    
    @StateObject var bridgeModule = BridgeModule.shared
    @Environment(\.dismiss) var dismiss
    @AppStorage(Constants.phoneThotStyle) private var phoneThotStyle: ThotStyle = .never
    @AppStorage(Constants.thotGenderOption) private var thotGenderOption: String = "female"

    enum Sheet: Identifiable {
        case completedWorkout([String: Any])
        var id: String { return "completedWorkoutSheet" }
    }
    
    @State var workoutComplete: Sheet?
    @State var workoutToPlan: Workout?
    @State var showExecersizeInfo: Bool = false
    
    var body: some View {
        ZStack {
            switch viewModel.status {
            case .loading:
                Text("Loading")
            case .showWorkout(let workout):
                VStack(spacing: 0) {
                    if bridgeModule.isInWorkout {
                        HStack {
                            CountdownView()
                        }
                        .padding()
                        .frame(maxWidth: .infinity)
                        
                        if phoneThotStyle != .off {
                            GeometryReader { metrics in
                                ZStack {
                                    PlayerView(player: $avPlayer)
                                        .frame(width: metrics.size.width * 1, height: metrics.size.height * 1)
                                        .onAppear{
                                            avPlayer.play()
                                        }
                                    
                                    Button(action: {
                                        if let assetURL = ((avPlayer.currentItem?.asset) as? AVURLAsset)?.url,
                                           let currentExtercise = bridgeModule.currentExerciseInfo.currentExercise,
                                           let otherVideoURL = VideoURLCreator.videoURL(
                                            thotStyle: VideoURLCreator.otherVideoType(forVideoURL: assetURL),
                                            gender: thotGenderOption,
                                            defaultVideoURLStr: currentExtercise.exercise.videoURL,
                                            exerciseName: currentExtercise.exercise.name,
                                            workout: bridgeModule.currentExerciseInfo.workout) {
                                            avPlayer = AVPlayer(url: otherVideoURL)
                                            avPlayer.play()
                                        }
                                    }, label: {
                                        Image(systemName: "arrow.triangle.2.circlepath.camera.fill")
                                            .frame(width: 44, height: 44)
                                            .foregroundColor(Color("appColor"))
                                    })
                                    .foregroundColor(.blue)
                                    .cornerRadius(4)
                                    .frame(width: 160, height: 120)
                                    .position(x: metrics.size.width - 22, y: metrics.size.height - 30)
                                    
                                    Button(action: {
                                        showExecersizeInfo.toggle()
                                    }, label: {
                                        Image(systemName: "info.circle.fill")
                                            .frame(width: 44, height: 44)
                                            .foregroundColor(Color("appColor"))
                                    })
                                    .foregroundColor(.blue)
                                    .cornerRadius(4)
                                    .frame(width: 120, height: 120)
                                    .position(x: 22, y: metrics.size.height - 30)
                                }
                            }
                            .padding([.top, .bottom])
                            .background(Color(uiColor: .tertiarySystemBackground))
                        }
                    }
                    
                    if !bridgeModule.isInWorkout {
                        InfoView(workout: workout)
                            .padding(.bottom)
                    }
                    
                    if bridgeModule.isInWorkout {
                        Divider()
                            .background(Color(uiColor: .secondaryLabel))
                        HStack {
                            Text("\(bridgeModule.currentExerciseInfo.currentRound) of \(bridgeModule.currentExerciseInfo.numberOfRoundsInCurrentSuperSet)")
                                .font(.title3)
                                .bold()
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .padding(.leading, 10)
                            
                            CurrentWorkoutElapsedTimeView()
                                .frame(maxWidth: .infinity, alignment: .center)
                            
                            Text("\(bridgeModule.currentExerciseInfo.allSupersetExecerciseIndex+1)/\(bridgeModule.currentExerciseInfo.workout?.allSupersetExecercise?.count ?? -99)")
                                .font(.title3)
                                .bold()
                                .frame(maxWidth: .infinity, alignment: .trailing)
                                .padding(.trailing, 10)
                        }
                        .padding([.top, .bottom])
                        .background(Color(uiColor: .tertiarySystemBackground))
                    }
                    
                    Divider()
                        .background(Color(uiColor: .secondaryLabel))
                    
                    ExerciseListView(workout: workout, showExecersizeInfo: $showExecersizeInfo)
                        .padding([.top, .bottom], 10)
                        .background(Color(uiColor: .systemGroupedBackground))
                    
                    ActionsView(completedWorkout: {
                        bridgeModule.completeWorkout()
                    }, planWorkout: { workout in
                        workoutToPlan = workout
                    }, workout: workout, showAddToCalendar: viewModel.isPreview, startWorkoutAction: {
                       startWorkout(workout: workout)
                    })
                    .frame(height: 44)
                    
                }
                .sheet(item: $workoutComplete) { item in
                    switch item {
                    case .completedWorkout(let data):
                        CompletedWorkoutView(postData: data,
                                             workout: workout,
                                             completedWorkoutDismissed: { uploaded in
                            if uploaded {
                                bridgeModule.resetCurrentWorkout()
                                dismiss()
                            }
                        })
                    }
                }
                .sheet(item: $workoutToPlan) { workout in
                    PlanWorkoutView(workout: workout, addedPlannedWorkout: {
                        dismiss()
                    })
                }
            }
        }
        .onChange(of: bridgeModule.currentExerciseInfo.allSupersetExecerciseIndex, perform: { _ in
            playVideos()
        })
        .onChange(of: bridgeModule.isInWorkout, perform: { _ in
            playVideos()
        })
        .onAppear{
            if let currentExtercise = bridgeModule.currentExerciseInfo.currentExercise {
                if let videoURL = VideoURLCreator.videoURL(
                    thotStyle: phoneThotStyle,
                    gender: thotGenderOption,
                    defaultVideoURLStr: currentExtercise.exercise.videoURL,
                    exerciseName: currentExtercise.exercise.name,
                    workout: bridgeModule.currentExerciseInfo.workout) {
                    avPlayer = AVPlayer(url: videoURL)
                    avPlayer.play()
                }
            }
            
            bridgeModule.completedWorkout = {
                if let workoutData = createWorkoutData() {
                    workoutComplete = .completedWorkout(workoutData)
                }
            }
        }
        .onReceive(NotificationCenter.default.publisher(
            for: UIScene.willEnterForegroundNotification)) { _ in
                avPlayer.play()
            }
    }
    
    func playVideos() {
        if let currentExtercise = bridgeModule.currentExerciseInfo.currentExercise {
            if let videoURL = VideoURLCreator.videoURL(
                thotStyle: phoneThotStyle,
                gender: thotGenderOption,
                defaultVideoURLStr: currentExtercise.exercise.videoURL,
                exerciseName: currentExtercise.exercise.name,
                workout: bridgeModule.currentExerciseInfo.workout) {
                avPlayer = AVPlayer(url: videoURL)
                avPlayer.play()
            }
        }
    }
    
    func startWorkout(workout: Workout) {
        bridgeModule.start(workout: workout)
    }
    
    func createWorkoutData() -> [String:Any]? {
        guard let workoutid = bridgeModule.currentExerciseInfo.workout?.id,
              let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload,
              let endTime = bridgeModule.workoutEndDate?.timeFormatForUpload else {
            return nil
        }
        let postBody = [
            "difficulty": 1,
            "workout_start_time": startTime,
            "workout_end_time": endTime,
            "workout": workoutid,
            "total_time": bridgeModule.currentWorkoutRunTimeInSeconds
        ] as [String : Any]
        
        return postBody
    }
}

struct WorkoutDetailView_Previews: PreviewProvider {
    static let workoutDetail = PreviewData.workout()
    static var previews: some View {
        WorkoutDetailView(viewModel: WorkoutDetailViewModel(workout: WorkoutDetailView_Previews.workoutDetail, status: .showWorkout(WorkoutDetailView_Previews.workoutDetail), isPreview: true))
    }
}
