import SwiftUI

public struct AudioCreateStyleTooltipModifier: ViewModifier {
    @Binding var showTooltip: Bool
    @State var isShowingTooltip = false
    @State private var shadowRadius: CGFloat = 4
    let accentColor: Color
    let buttonHeight: CGFloat
    let tooltip: Tooltip?
    let configuration: Tooltip.Configuration
    let onDismiss: () -> Void

    public init(
        showTooltip: Binding<Bool>,
        tooltip: Tooltip?,
        accentColor: Color,
        buttonHeight: CGFloat,
        onDismiss: @escaping () -> Void
    ) {
        self._showTooltip = showTooltip
        self.tooltip = tooltip
        self.accentColor = accentColor
        self.buttonHeight = buttonHeight
        self.configuration = .audioCreateStyle
        self.onDismiss = onDismiss
    }

    public func body(content: Content) -> some View {
        content
            .background(
                UnevenRoundedRectangle(cornerRadii: .init(bottomLeading: 8, bottomTrailing: 8))
                    .foregroundColor(Color.SemanticV1.textInvert)
                    .shadow(color: isShowingTooltip ? accentColor : .clear, radius: isShowingTooltip ? shadowRadius : 0)
                    .opacity(isShowingTooltip ? 1 : 0)
            )
            .overlay {
                if isShowingTooltip, let tooltip {
                    TooltipView(
                        tooltip: tooltip,
                        maxWidth: configuration.maxWidth,
                        accentColor: accentColor,
                        onButtonTap: onDismiss
                    )
                    .transition(
                        .asymmetric(
                            insertion: .scale(scale: 0.9)
                                .combined(with: .opacity),
                            removal: .scale(scale: 0.9)
                                .combined(with: .opacity)
                        )
                    )
                    .position(
                        tooltipPosition(
                            in: buttonHeight,
                            for: configuration.maxWidth,
                            anchor: configuration.anchor,
                            spacing: configuration.spacing
                        )
                    )
                    .zIndex(.infinity)
                }
            }
            .onChange(of: showTooltip) { _, isShowing in
                if isShowing {
                    withAnimation(.spring(duration: 0.4)) {
                        isShowingTooltip = true
                    }
                    withAnimation(.easeInOut(duration: 1.5).repeatForever(autoreverses: true)) {
                        shadowRadius = configuration.anchorObjectShadowRadius
                    }
                } else {
                    withAnimation(.easeInOut(duration: 0.2)) {
                        isShowingTooltip = false
                        shadowRadius = 0
                    }
                }
            }
    }

    private func tooltipPosition(
        in buttonSize: CGFloat,
        for tooltipWidth: CGFloat,
        anchor: Tooltip.Anchor,
        spacing _: CGFloat
    ) -> CGPoint {
        switch anchor {
        case .up(let offset):
            return CGPoint(
                x: tooltipWidth / 2,
                y: buttonSize + offset
            )

        default:
            // Audio create style tooltip only supports up positioning
            return CGPoint(x: 0, y: 0)
        }
    }
}
