//
//  ExternalView.swift
//  Werkout_ios
//
//  Created by Trey Tartt on 6/13/23.
//

import SwiftUI
import AVKit

struct ExternalWorkoutDetailView: View {
    @StateObject var bridgeModule = BridgeModule.shared
    @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!)
    @State var smallAVPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!)
    @AppStorage(Constants.extThotStyle) private var extThotStyle: ThotStyle = .never
    @AppStorage(Constants.extShowNextVideo) private var extShowNextVideo: Bool = false
    @AppStorage(Constants.thotGenderOption) private var thotGenderOption: String = "female"

    var body: some View {
        ZStack {
            if let workout = bridgeModule.currentExerciseInfo.workout {
                GeometryReader { metrics in
                    VStack {
                        HStack {
                            if extThotStyle != .off {
                                PlayerView(player: $avPlayer)
                                    .frame(width: metrics.size.width * 0.5, height: metrics.size.height * 0.8)
                                    .onAppear{
                                        avPlayer.play()
                                    }
                            }
                            
                            VStack {
                                ExtExerciseList(workout: workout,
                                                allSupersetExecerciseIndex: bridgeModule.currentExerciseInfo.allSupersetExecerciseIndex)
                                
                                if let currentExercisePositionString = bridgeModule.currentExercisePositionString {
                                    Text(currentExercisePositionString)
                                        .font(Font.system(size: 75))
                                        .scaledToFit()
                                        .minimumScaleFactor(0.01)
                                        .lineLimit(1)
                                        .padding()
                                }
                            }
                            .frame(width: metrics.size.width * 0.4, height: metrics.size.height * 0.8)
                        }
                        
                        HStack {
                            if extShowNextVideo && extThotStyle != .off {
                                ExtCountdownView()
                                    .frame(width: metrics.size.width * 0.8, height: metrics.size.height * 0.2)
                                    .padding(.leading, 50)
                                    .padding(.trailing, 5)
                                
                                PlayerView(player: $smallAVPlayer)
                                    .frame(width: metrics.size.width * 0.2, height: metrics.size.height * 0.2)
                                    .padding(.trailing, 50)
                                    .onAppear{
                                        avPlayer.play()
                                    }
                            } else {
                                ExtCountdownView()
                                    .frame(width: metrics.size.width-50, height: metrics.size.height * 0.2)
                                    .padding([.leading, .trailing], 50)
                            }
                        }
                    }
                }
            } else {
                Image("icon")
                    .resizable()
                    .edgesIgnoringSafeArea(.all)
                    .scaledToFill()
            }
        }
        .onChange(of: bridgeModule.isInWorkout, perform: { newValue in
            if let currentExtercise = bridgeModule.currentExerciseInfo.currentExercise {
                if let videoURL = VideoURLCreator.videoURL(
                    thotStyle: extThotStyle,
                    gender: thotGenderOption,
                    defaultVideoURLStr: currentExtercise.exercise.videoURL,
                    exerciseName: currentExtercise.exercise.name,
                    workout: bridgeModule.currentExerciseInfo.workout) {
                    avPlayer = AVPlayer(url: videoURL)
                    avPlayer.play()
                    
                    if extShowNextVideo {
                        if let smallVideoURL = VideoURLCreator.videoURL(
                            thotStyle: VideoURLCreator.otherVideoType(forVideoURL: videoURL),
                            gender: thotGenderOption,
                            defaultVideoURLStr: currentExtercise.exercise.videoURL,
                            exerciseName: currentExtercise.exercise.name,
                            workout: bridgeModule.currentExerciseInfo.workout) {
                            smallAVPlayer = AVPlayer(url: smallVideoURL)
                            smallAVPlayer.play()
                        }
                    }
                }
            }
        })
        .onChange(of: bridgeModule.currentExerciseInfo.exerciseIndex, perform: { newValue in
            if let currentExtercise = bridgeModule.currentExerciseInfo.currentExercise {
                if let videoURL = VideoURLCreator.videoURL(
                    thotStyle: extThotStyle,
                    gender: thotGenderOption,
                    defaultVideoURLStr: currentExtercise.exercise.videoURL,
                    exerciseName: currentExtercise.exercise.name,
                    workout: bridgeModule.currentExerciseInfo.workout) {
                    avPlayer = AVPlayer(url: videoURL)
                    avPlayer.play()
                    
                    if extShowNextVideo {
                        if let smallVideoURL = VideoURLCreator.videoURL(
                            thotStyle: .never,
                            gender: thotGenderOption,
                            defaultVideoURLStr: BridgeModule.shared.currentExerciseInfo.nextExerciseInfo?.exercise.videoURL,
                            exerciseName: BridgeModule.shared.currentExerciseInfo.nextExerciseInfo?.exercise.name,
                            workout: bridgeModule.currentExerciseInfo.workout) {
                            smallAVPlayer = AVPlayer(url: smallVideoURL)
                            smallAVPlayer.play()
                        }
                    }
                }
            }
        })
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(bridgeModule.currentExerciseInfo.workout == nil ? Color(red: 157/255, green: 138/255, blue: 255/255) : Color(uiColor: .systemBackground))
        .onReceive(NotificationCenter.default.publisher(
            for: UIScene.willEnterForegroundNotification)) { _ in
                avPlayer.play()
                smallAVPlayer.play()
            }
    }
}

struct TitleView: View {
    @ObservedObject var bridgeModule = BridgeModule.shared
    
    var body: some View {
        HStack {
            if let workout = bridgeModule.currentExerciseInfo.workout {
                Text(workout.name)
                    .font(Font.system(size: 100))
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
            
            if bridgeModule.currentWorkoutRunTimeInSeconds > -1 {
                Text("\(bridgeModule.currentWorkoutRunTimeInSeconds)")
                    .font(Font.system(size: 100))
                    .frame(maxWidth: .infinity, alignment: .trailing)
                    .padding(.trailing, 100)
            }
        }
    }
}

struct ExtExerciseList: View {
    var workout: Workout
    var allSupersetExecerciseIndex: Int
    
    var body: some View {
        if let allSupersetExecercise = workout.allSupersetExecercise {
            ZStack {
                ScrollViewReader { proxy in
                    List() {
                        ForEach(allSupersetExecercise.indices, id: \.self) { supersetExecerciseIdx in
                            let supersetExecercise = allSupersetExecercise[supersetExecerciseIdx]
                            HStack {
                                if supersetExecerciseIdx == allSupersetExecerciseIndex {
                                    Image(systemName: "checkmark")
                                        .foregroundColor(.green)
                                        .font(Font.system(size: 55))
                                        .minimumScaleFactor(0.01)
                                        .lineLimit(1)
                                        .foregroundColor(.green)
                                }
                                
                                Text(supersetExecercise.exercise.name)
                                    .font(Font.system(size: 55))
                                    .minimumScaleFactor(0.01)
                                    .lineLimit(3)
                                    .padding()
                                
                                Spacer()
                            }
                            .id(supersetExecerciseIdx)
                        }
                    }
                    .onChange(of: allSupersetExecerciseIndex, perform: { newValue in
                        withAnimation {
                            proxy.scrollTo(allSupersetExecerciseIndex, anchor: .top)
                        }
                    })
                    
                }
                VStack {
                    Text("\(allSupersetExecerciseIndex+1)/\(workout.allSupersetExecercise?.count ?? 0)")
                        .font(Font.system(size: 55))
                        .minimumScaleFactor(0.01)
                        .lineLimit(1)
                        .padding()
                        .bold()
                        .foregroundColor(.white)
                        .background(
                            Capsule()
                                .strokeBorder(Color.black, lineWidth: 0.8)
                                .background(Color(uiColor: UIColor(red: 148/255,
                                                                   green: 0,
                                                                   blue: 211/255,
                                                                   alpha: 0.5)))
                                .clipped()
                        )
                        .clipShape(Capsule())
                    
                    Spacer()
                }
            }
        }
    }
}

struct ExtCountdownView: View {
    @StateObject var bridgeModule = BridgeModule.shared
    
    var body: some View {
        GeometryReader { metrics in
            VStack {
                if let currenExercise = bridgeModule.currentExerciseInfo.currentExercise {
                    HStack {
                        Text(currenExercise.exercise.extName)
                            .font(.system(size: 200))
                            .scaledToFit()
                            .minimumScaleFactor(0.01)
                            .lineLimit(1)
                            .frame(maxWidth: .infinity, alignment: .leading)
                        
                        if bridgeModule.currentWorkoutRunTimeInSeconds > -1 {
                            Text("\(Double(bridgeModule.currentWorkoutRunTimeInSeconds).asString(style: .positional))")
                                .font(Font.system(size: 100))
                                .scaledToFit()
                                .minimumScaleFactor(0.01)
                                .lineLimit(1)
                                .frame(maxWidth: .infinity, alignment: .trailing)
                                .padding(.trailing, 100)
                        }
                    }
                    .frame(height: metrics.size.height * 0.5)
                    
                    HStack {
                        if let duration = currenExercise.duration,
                           duration > 0 {
                            ProgressView(value: Float(bridgeModule.currentExerciseTimeLeft), total: Float(duration))
                                .scaleEffect(x: 1, y: 6, anchor: .center)
                            Text("\(bridgeModule.currentExerciseTimeLeft)")
                                .font(Font.system(size: 100))
                                .scaledToFit()
                                .minimumScaleFactor(0.01)
                                .lineLimit(1)
                                .padding(.leading)
                                .padding(.trailing, 100)
                        }
                        
                        if let reps = currenExercise.reps,
                           reps > 0 {
                            Text(" X \(reps)")
                                .font(Font.system(size: 100))
                                .scaledToFit()
                                .minimumScaleFactor(0.01)
                                .lineLimit(1)
                                .frame(maxWidth: .infinity, alignment: .leading)
                        }
                        
                        if let weight = currenExercise.weight,
                           weight > 0 {
                            Text(" @ \(weight)")
                                .font(Font.system(size: 100))
                                .scaledToFit()
                                .minimumScaleFactor(0.01)
                                .lineLimit(1)
                                .padding(.trailing, 100)
                                .frame(maxWidth: .infinity, alignment: .leading)
                        }
                    }
                    .frame(height: metrics.size.height * 0.5)
                }
            }
        }
    }
}

//struct ExternalWorkoutDetailView_Previews: PreviewProvider {
//    static var bridge = BridgeModule.shared
//    
//    static var previews: some View {
//        ExternalWorkoutDetailView().environmentObject({ () -> BridgeModule in
//            let envObj = BridgeModule.shared
//            envObj.currentWorkout = nil //PreviewData.workout()
//            bridge.currentExercise = PreviewData.workout().exercisesSortedByCreated_at.first!
//            return envObj
//        }() )
//    }
//}
