import SwiftUI

// MARK: - Glass Back Button (circular, like screenshot reference)

struct GlassBackButton: View {
    let action: () -> Void
    var size: CGFloat = 44

    var body: some View {
        Button(action: action) {
            Image(systemName: "chevron.left")
                .font(.system(size: 18, weight: .semibold))
                .foregroundStyle(.white)
                .frame(width: size, height: size)
        }
        .background {
            glassCircle
        }
        .clipShape(Circle())
    }

    private var glassCircle: some View {
        // Use TelegramGlassCircle for all versions — it supports iOS 26 natively
        // (UIGlassEffect) and has isUserInteractionEnabled = false, guaranteeing
        // touches pass through. SwiftUI .glassEffect() intercepts taps.
        TelegramGlassCircle()
    }
}

// MARK: - Primary Button (Liquid Glass)

struct RosettaPrimaryButtonStyle: ButtonStyle {
    var isEnabled: Bool = true

    private var fillColor: Color {
        isEnabled ? RosettaColors.primaryBlue : Color(white: 0.22)
    }

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .background {
                Capsule()
                    .fill(fillColor.opacity(configuration.isPressed ? 0.7 : 1.0))
            }
            .clipShape(Capsule())
            .scaleEffect(configuration.isPressed && isEnabled ? 0.97 : 1.0)
            .animation(.easeOut(duration: 0.15), value: configuration.isPressed)
            .allowsHitTesting(isEnabled)
    }
}

// MARK: - Settings Row (Telegram-like instant press highlight)

enum SettingsRowPosition {
    case alone, top, middle, bottom
}

/// Instant press highlight using DragGesture — bypasses ScrollView's touch delay.
private struct SettingsHighlightModifier: ViewModifier {
    let position: SettingsRowPosition
    let cornerRadius: CGFloat

    @GestureState private var isPressed = false

    func body(content: Content) -> some View {
        let shape = shape(for: position)
        content
            .buttonStyle(.plain)
            .background(shape.fill(isPressed ? Color.white.opacity(0.08) : Color.clear))
            .clipShape(shape)
            .simultaneousGesture(
                DragGesture(minimumDistance: 5)
                    .updating($isPressed) { value, state, _ in
                        state = abs(value.translation.height) < 10
                            && abs(value.translation.width) < 10
                    }
            )
    }

    private func shape(for position: SettingsRowPosition) -> UnevenRoundedRectangle {
        switch position {
        case .alone:
            UnevenRoundedRectangle(topLeadingRadius: cornerRadius, bottomLeadingRadius: cornerRadius, bottomTrailingRadius: cornerRadius, topTrailingRadius: cornerRadius, style: .continuous)
        case .top:
            UnevenRoundedRectangle(topLeadingRadius: cornerRadius, bottomLeadingRadius: 0, bottomTrailingRadius: 0, topTrailingRadius: cornerRadius, style: .continuous)
        case .middle:
            UnevenRoundedRectangle(topLeadingRadius: 0, bottomLeadingRadius: 0, bottomTrailingRadius: 0, topTrailingRadius: 0, style: .continuous)
        case .bottom:
            UnevenRoundedRectangle(topLeadingRadius: 0, bottomLeadingRadius: cornerRadius, bottomTrailingRadius: cornerRadius, topTrailingRadius: 0, style: .continuous)
        }
    }
}

extension View {
    func settingsHighlight(position: SettingsRowPosition = .alone, cornerRadius: CGFloat = 26) -> some View {
        modifier(SettingsHighlightModifier(position: position, cornerRadius: cornerRadius))
    }
}

// MARK: - Shine Overlay (Telegram-style color sweep)
//
// Instead of a white glare, a lighter/cyan tint of the button's own colour
// glides across — exactly the look Telegram uses on its primary CTA.

struct ShineModifier: ViewModifier {
    let speed: Double
    let highlightWidth: CGFloat
    let tintColor: Color
    let delay: Double

    @State private var phase: CGFloat = 0

    func body(content: Content) -> some View {
        content
            .overlay {
                GeometryReader { geo in
                    let w = geo.size.width * highlightWidth
                    let travel = geo.size.width + w
                    let currentX = -w + phase * travel

                    LinearGradient(
                        stops: [
                            .init(color: .clear, location: 0),
                            .init(color: tintColor, location: 0.45),
                            .init(color: tintColor, location: 0.55),
                            .init(color: .clear, location: 1),
                        ],
                        startPoint: .leading,
                        endPoint: .trailing
                    )
                    .frame(width: w, height: geo.size.height)
                    .offset(x: currentX)
                    .frame(width: geo.size.width, height: geo.size.height, alignment: .leading)
                }
                .clipShape(Capsule())
                .allowsHitTesting(false)
            }
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                    withAnimation(
                        .easeInOut(duration: speed)
                        .repeatForever(autoreverses: false)
                    ) {
                        phase = 1
                    }
                }
            }
    }
}

extension View {
    func shine(
        speed: Double = 2.0,
        highlightWidth: CGFloat = 0.55,
        tintColor: Color = Color(red: 0.35, green: 0.82, blue: 0.98).opacity(0.50),
        delay: Double = 0.3
    ) -> some View {
        modifier(ShineModifier(
            speed: speed,
            highlightWidth: highlightWidth,
            tintColor: tintColor,
            delay: delay
        ))
    }

    /// Legacy alias
    func shimmer() -> some View {
        shine()
    }
}

// MARK: - Stagger Animation Helper

struct StaggeredAppearance: ViewModifier {
    let key: String
    let index: Int
    let baseDelay: Double
    let stagger: Double
    @State private var isVisible: Bool

    /// Tracks which screen keys have already animated so we don't replay on re-navigation.
    private static var animatedKeys: Set<String> = []

    init(key: String, index: Int, baseDelay: Double, stagger: Double) {
        self.key = key
        self.index = index
        self.baseDelay = baseDelay
        self.stagger = stagger
        // Start visible immediately if this screen already animated — no flash frame.
        _isVisible = State(initialValue: Self.animatedKeys.contains(key))
    }

    func body(content: Content) -> some View {
        content
            .opacity(isVisible ? 1.0 : 0.0)
            .offset(y: isVisible ? 0 : 12)
            .onAppear {
                guard !isVisible else { return }
                let delay = baseDelay + Double(index) * stagger
                withAnimation(.easeOut(duration: 0.4).delay(delay)) {
                    isVisible = true
                }
                Self.animatedKeys.insert(key)
            }
    }
}

extension View {
    func staggeredAppearance(
        key: String = "default",
        index: Int,
        baseDelay: Double = 0.2,
        stagger: Double = 0.05
    ) -> some View {
        modifier(StaggeredAppearance(key: key, index: index, baseDelay: baseDelay, stagger: stagger))
    }
}
