//
//  PrimaryButton.swift
//  lichunWebsocket
//
//  Primary button component with cozy styling
//

import SwiftUI

struct PrimaryButton: View {
    let title: String
    let action: () -> Void
    var backgroundColor: Color = AppColors.primary
    /// Text/spinner color. Defaults to white, which reads well on the saturated
    /// brand backgrounds. Pass an explicit color when using a light background
    /// (e.g. a white "card" button) so the label stays legible in light AND dark mode.
    var foregroundColor: Color = .white
    var isDisabled: Bool = false
    var isLoading: Bool = false

    @State private var isGlowing = false

    var body: some View {
        Button(action: {
            if !isDisabled && !isLoading {
                hapticFeedback(style: .medium)

                // Trigger glow animation
                withAnimation(.easeOut(duration: 0.4)) {
                    isGlowing = true
                }
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
                    isGlowing = false
                }

                action()
            }
        }) {
            HStack(spacing: AppSpacing.sm) {
                if isLoading {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle(tint: foregroundColor))
                } else {
                    Text(title)
                        .font(.appHeadline)
                        .foregroundColor(foregroundColor)
                }
            }
            .frame(maxWidth: .infinity)
            .frame(height: AppSpacing.buttonHeight)
            .background(
                Group {
                    if isDisabled {
                        AppColors.disabledText
                    } else {
                        LinearGradient(
                            colors: [backgroundColor, backgroundColor.darker(by: 0.1)],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    }
                }
            )
            .cornerRadius(AppSpacing.pillCornerRadius)
            .shadow(
                color: isDisabled ? .clear : backgroundColor.opacity(isGlowing ? 0.7 : 0.4),
                radius: isGlowing ? 16 : AppSpacing.Shadow.radiusSoft,
                x: 0,
                y: AppSpacing.Shadow.offsetY
            )
            // Additional ripple glow ring
            .overlay(
                RoundedRectangle(cornerRadius: AppSpacing.pillCornerRadius)
                    .stroke(backgroundColor, lineWidth: isGlowing ? 0 : 3)
                    .scaleEffect(isGlowing ? 1.3 : 1.0)
                    .opacity(isGlowing ? 0 : 0.5)
            )
        }
        .buttonStyle(SquishButtonStyle())
        .disabled(isDisabled || isLoading)
    }
}

/// The canonical "satisfying press" style used app-wide: a subtle, fast squish
/// on press-down so every tappable surface feels responsive and consistent.
///
/// The curve is intentionally quick with little overshoot (`AppAnimations.quick`)
/// — subtle and fast rather than springy and slow.
///
/// `pressHaptic` defaults to `nil` so buttons that already fire their own haptic
/// in their action closure (PrimaryButton, SecondaryButton, CozyIconButton, and
/// many call sites) don't double-buzz. Pass `.soft` for otherwise-silent buttons
/// (e.g. bare icon buttons) that have no other tactile feedback, giving them a
/// gentle press-down tick.
struct SquishButtonStyle: ButtonStyle {
    var scale: CGFloat = 0.96
    var pressHaptic: UIImpactFeedbackGenerator.FeedbackStyle? = nil

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? scale : 1.0)
            .animation(AppAnimations.quick, value: configuration.isPressed)
            .onChange(of: configuration.isPressed) { isPressed in
                if isPressed, let pressHaptic {
                    hapticFeedback(style: pressHaptic)
                }
            }
    }
}

// MARK: - Preview
#if DEBUG
struct PrimaryButton_Previews: PreviewProvider {
    static var previews: some View {
        VStack(spacing: 20) {
            PrimaryButton(title: "Continue") {
                print("Tapped!")
            }

            PrimaryButton(
                title: "Send Message",
                action: {},
                backgroundColor: AppColors.accent
            )

            PrimaryButton(
                title: "Disabled",
                action: {},
                isDisabled: true
            )

            PrimaryButton(
                title: "Loading",
                action: {},
                isLoading: true
            )
        }
        .padding()
        .background(AppColors.background)
    }
}
#endif
