import SwiftUI

struct PlayerBackendView: View {
    #if os(iOS)
        @Environment(\.verticalSizeClass) private var verticalSizeClass
    #endif
    @EnvironmentObject<PlayerModel> private var player
    @EnvironmentObject<ThumbnailsModel> private var thumbnails

    var body: some View {
        ZStack(alignment: .top) {
            Group {
                switch player.activeBackend {
                case .mpv:
                    player.mpvPlayerView
                case .appleAVPlayer:
                    player.avPlayerView
                }
            }
            .overlay(GeometryReader { proxy in
                Color.clear
                    .onAppear { player.playerSize = proxy.size }
                    .onChange(of: proxy.size) { _ in player.playerSize = proxy.size }
                    .onChange(of: player.controls.presentingOverlays) { _ in player.playerSize = proxy.size }
            })
            #if os(iOS)
            .padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0)
            #endif

            #if !os(tvOS)
                PlayerGestures()
                PlayerControls(player: player, thumbnails: thumbnails)
                #if os(iOS)
                    .padding(.top, controlsTopPadding)
                    .padding(.bottom, controlsBottomPadding)
                #endif
            #else
                hiddenControlsButton
            #endif
        }
        #if os(iOS)
        .statusBarHidden(fullScreenLayout)
        #endif
    }

    var fullScreenLayout: Bool {
        #if os(iOS)
            player.playingFullScreen || verticalSizeClass == .compact
        #else
            player.playingFullScreen
        #endif
    }

    #if os(iOS)
        var controlsTopPadding: Double {
            guard fullScreenLayout else { return 0 }

            if UIDevice.current.userInterfaceIdiom != .pad {
                return verticalSizeClass == .compact ? SafeArea.insets.top : 0
            } else {
                return SafeArea.insets.top.isZero ? SafeArea.insets.bottom : SafeArea.insets.top
            }
        }

        var controlsBottomPadding: Double {
            guard fullScreenLayout else { return 0 }

            if UIDevice.current.userInterfaceIdiom != .pad {
                return fullScreenLayout && verticalSizeClass == .compact ? SafeArea.insets.bottom : 0
            } else {
                return fullScreenLayout ? SafeArea.insets.bottom : 0
            }
        }
    #endif

    #if os(tvOS)
        private var hiddenControlsButton: some View {
            VStack {
                Button {
                    player.controls.show()
                } label: {
                    EmptyView()
                }
                .offset(y: -100)
                .buttonStyle(.plain)
                .background(Color.clear)
                .foregroundColor(.clear)
            }
        }
    #endif
}

struct PlayerBackendView_Previews: PreviewProvider {
    static var previews: some View {
        PlayerBackendView()
            .injectFixtureEnvironmentObjects()
    }
}