import SwiftUI

public struct TooltipModifier: ViewModifier {
    @Binding private var tooltip: Tooltip?
    private let position: CGPoint
    private let accentColor: Color
    private let onButtonTap: () -> Void
    private let dismiss: () -> Void

    public init(
        tooltip: Binding<Tooltip?>,
        position: (x: CGFloat, y: CGFloat),
        accentColor: Color,
        onButtonTap: @escaping () -> Void,
        dismiss: (() -> Void)? = nil
    ) {
        self._tooltip = tooltip
        self.position = CGPoint(x: position.x, y: position.y)
        self.accentColor = accentColor
        self.onButtonTap = onButtonTap
        self.dismiss = dismiss ?? {
            withAnimation(.easeInOut(duration: 0.2)) {
                tooltip.wrappedValue = nil
            }
        }
    }

    public func body(content: Content) -> some View {
        content
            .overlay {
                if let tooltip = tooltip {
                    ZStack {
                        // This is a workaround since using Color.clear acts as a
                        // pass-throughview and doesn't trigger the onTapGesture action.
                        Color.black
                            .opacity(0.01)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .onTapGesture(perform: dismiss)

                        TooltipView(
                            tooltip: tooltip,
                            maxWidth: tooltip.configuration.maxWidth,
                            accentColor: accentColor,
                            onButtonTap: onButtonTap
                        )
                        .position(position)
                    }
                    .transition(.opacity)
                    .zIndex(.infinity)
                }
            }
    }
}

public extension View {
    @ViewBuilder
    func tooltip(
        _ tooltip: Binding<Tooltip?>,
        position: (x: CGFloat, y: CGFloat),
        accentColor: Color = Color.SemanticV2.accentBrand,
        onButtonTap: @escaping () -> Void,
        dismiss: (() -> Void)? = nil
    ) -> some View {
        modifier(
            TooltipModifier(
                tooltip: tooltip,
                position: position,
                accentColor: accentColor,
                onButtonTap: onButtonTap,
                dismiss: dismiss
            )
        )
    }
}
