import APIClient
import ComponentLibrary
import ComposableArchitecture
import CoreMedia
import FeatureClipDetail
import Localization
import PlayerClient
import SwiftUI
import Utilities

public struct WaveformEditorControls: View {
    @Binding var isPlaying: Bool
    let leftHandleTimeMarkerCaption: String?
    let rightHandleTimeMarkerCaption: String?
    let leftHandleTime: String
    let rightHandleTime: String
    @FocusState public var focusedField: Field?
    let didManuallyEditLeftHandleTime: (String) -> Void
    let didManuallyEditRightHandleTime: (String) -> Void
    let resetEditableTimestampFields: () -> Void
    let isWaitingToPlay: Bool

    // Toggled when a parent view dismisses the keyboard
    let shouldDismissKeyboard: Bool
    let shouldSaveTimestampsAndDismissKeyboard: Bool

    // Set when the user manually types in the time stamp text field
    @State var manuallyUpdatedLeftHandleTime: String = ""
    @State var manuallyUpdatedRightHandleTime: String = ""

    public enum Field: Hashable {
        case leftHandleTimestamp
        case rightHandleTimestamp
    }

    var showLeftHandleTimestamp: Bool {
        leftHandleTimeMarkerCaption != nil
    }

    var showRightHandleTimestamp: Bool {
        rightHandleTimeMarkerCaption != nil
    }

    public var body: some View {
        ZStack {
            // Handles tapping outside the text field to dismiss the
            // keyboard and submit the new time
            tapToDismissBackground
            HStack(spacing: 0) {
                playPauseButton
                Spacer()
                if showLeftHandleTimestamp {
                    editableTimestamp(isLeft: true)
                }
                if showRightHandleTimestamp {
                    editableTimestamp(isLeft: false)
                }
            }
            .padding(6)
        }
        .ignoresSafeArea()
        .onChange(of: shouldDismissKeyboard) { _, newValue in
            if newValue {
                handleDismissKeyboard()
            }
        }
        .onChange(of: shouldSaveTimestampsAndDismissKeyboard) { _, newValue in
            if newValue {
                handleDismissKeyboard(saveTimestamps: true)
            }
        }
    }

    @ViewBuilder
    private var tapToDismissBackground: some View {
        Color.clear
            .contentShape(.rect)
            .onTapGesture { handleDismissKeyboard() }
    }

    @ViewBuilder
    private var playPauseButton: some View {
        Image(systemName: isPlaying ? "pause.fill" : "play.fill")
            .foregroundColor(Color.SemanticV1.textSecondary)
            .frame(width: 24, height: 24)
            .padding(8)
            .contentShape(.rect)
            .onTapGesture {
                isPlaying.toggle()
            }
            .disabled(isWaitingToPlay)
            .overlay {
                ProgressView()
                    .progressViewStyle(.circular)
                    .opacity(isWaitingToPlay ? 1 : 0)
            }
    }

    @ViewBuilder
    private func editableTimestamp(isLeft: Bool) -> some View {
        EditableTimestampField(
            label: isLeft ? leftHandleTimeMarkerCaption ?? "" : rightHandleTimeMarkerCaption ?? "",
            time: isLeft ? leftHandleTime : rightHandleTime,
            updatedTime: isLeft ? $manuallyUpdatedLeftHandleTime : $manuallyUpdatedRightHandleTime,
            isLeftHandle: isLeft,
            onSubmit: { time in
                didManuallyEditRightHandleTime(time)
                if isLeft {
                    manuallyUpdatedLeftHandleTime = ""
                } else {
                    manuallyUpdatedRightHandleTime = ""
                }
            },
            onTap: {
                focusedField = isLeft ? .leftHandleTimestamp : .rightHandleTimestamp
            },
            onFocus: {
                focusedField = isLeft ? .leftHandleTimestamp : .rightHandleTimestamp
            }
        )
        .focused($focusedField, equals: isLeft ? .leftHandleTimestamp : .rightHandleTimestamp)
        .onTapGesture {
            focusedField = isLeft ? .leftHandleTimestamp : .rightHandleTimestamp
        }
    }

    private func handleDismissKeyboard(saveTimestamps: Bool = false) {
        focusedField = nil
        if manuallyUpdatedLeftHandleTime != "", saveTimestamps {
            didManuallyEditLeftHandleTime(manuallyUpdatedLeftHandleTime)
            manuallyUpdatedLeftHandleTime = ""
        } else if manuallyUpdatedRightHandleTime != "", saveTimestamps {
            didManuallyEditRightHandleTime(manuallyUpdatedRightHandleTime)
            manuallyUpdatedRightHandleTime = ""
        } else {
            manuallyUpdatedLeftHandleTime = ""
            manuallyUpdatedRightHandleTime = ""
            resetEditableTimestampFields()
        }
    }
}
