import ComposableArchitecture
import Localization
import SwiftUI
import Utilities
import ComponentLibrary

public struct HookSnippetSelectionView: View {
    public static let backgroundColor = Color.SemanticV1.backgroundTertiary

    let store: StoreOf<HookSnippetSelectionReducer>

    public init(store: StoreOf<HookSnippetSelectionReducer>) {
        self.store = store
    }

    public var body: some View {
        content
            .environment(\.colorScheme, .dark)
            .padding(.horizontal, 16)
            .padding(.vertical, 20)
            .background(Self.backgroundColor)
    }

    private var content: some View {
        VStack(spacing: 16) {
            HStack {
                headerButton(
                    icon: .Icon.close,
                    foregroundColor: .SemanticV2.foregroundPrimary,
                    backgroundColor: .SemanticV2.backgroundFogThin,
                    action: { store.send(.cancelTapped) }
                )
                // Keep the view here, so we can keep the text centered
                .opacity(store.showCancelButton ? 1 : 0)
                    .disabled(!store.showCancelButton)

                Spacer()

                VStack(spacing: 4) {
                    Text(L10n.FeatureHooks.chooseStartPoint)
                        .typographyV1(.heading4)
                        .foregroundColor(.SemanticV2.foregroundPrimary)

                    Text(L10n.FeatureHooks.scrubToChooseStart)
                        .typographyV1(.bodySmall)
                        .foregroundColor(.SemanticV2.foregroundTertiary)
                }

                Spacer()

                headerButton(
                    icon: .Icon.checkV1,
                    foregroundColor: .SemanticV2.backgroundPrimary,
                    backgroundColor: .SemanticV2.foregroundPrimary,
                    action: { store.send(.saveTapped) }
                )
            }

            timeSlider(
                duration: store.duration,
                snippetStartTime: store.snippetStartTime,
                onSnippetStartTimeChanged: { newTime in
                    store.send(.snippetStartTimeChanged(newTime))
                }
            )
        }
    }

    private func headerButton(
        icon: Image,
        foregroundColor: Color,
        backgroundColor: Color,
        action: @escaping () -> Void
    ) -> some View {
        Button(action: {
            withAnimation(.easeInOut(duration: 0.3)) {
                action()
            }
        }) {
            icon
                .renderingMode(.template)
                .resizable()
                .frame(width: 32, height: 32)
                .foregroundColor(foregroundColor)
                .padding(6)
                .background(backgroundColor)
                .clipShape(.circle)
        }
    }

    private func timeSlider(
        duration: TimeInterval,
        snippetStartTime: TimeInterval,
        onSnippetStartTimeChanged: @escaping (TimeInterval) -> Void
    ) -> some View {
        let thumbSize = CGSize(width: 10, height: 10)

        return HStack(
            alignment: .center,
            spacing: 8
        ) {
            Text(snippetStartTime.formatTimeConditional)
                .typographyV1(.monospaceSmall)
                .foregroundColor(.SemanticV1.textPrimary)
                .monospacedDigit()

            GeometryReader { geometry in
                ZStack(alignment: .leading) {
                    Capsule()
                        .fill(Color.SemanticV1.backgroundTertiary)
                        .frame(height: 4)

                    Capsule()
                        .fill(Color.SemanticV1.textPrimary)
                        .frame(
                            width: geometry.size.width * CGFloat(snippetStartTime / max(duration, 1)),
                            height: 4
                        )

                    Circle()
                        .fill(Color.SemanticV1.textPrimary)
                        .frame(width: thumbSize.width, height: thumbSize.height)
                        .offset(
                            x: {
                                let percent = max(0, min(1, snippetStartTime / max(duration, 1)))
                                let offset = geometry.size.width * percent
                                return offset
                            }()
                        )
                }
                .contentShape(Rectangle())
                .gesture(
                    DragGesture(minimumDistance: 0)
                        .onChanged { value in
                            let percent = max(0, min(1, value.location.x / geometry.size.width))
                            let newTime = duration * percent
                            onSnippetStartTimeChanged(newTime)
                        }
                )
            }
            .frame(height: thumbSize.height)

            Text(duration.formatTimeConditional)
                .typographyV1(.monospaceSmall)
                .foregroundColor(.SemanticV1.textPrimary)
                .monospacedDigit()
        }
    }
}
