import ComposableArchitecture
import InAppNotificationClient
import SwiftUI

public struct NotificationsBadgeModifier: ViewModifier {
    /// If true, we using drawingGroup so that iOS26 toolbar blends correctly
    public var isToolbarItem: Bool = true

    @Shared(.inMemory(.inAppNotificationsState)) private var inAppNotificationsState: NotificationLoadingState = .loading
    @Shared(.inMemory(.hasUnreadNotifications)) private var hasUnreadNotifications: Bool = false

    private let dotDimension: CGFloat = 9

    public init(isToolbarItem: Bool = true) {
        self.isToolbarItem = isToolbarItem
    }

    public func body(content: Content) -> some View {
        if isToolbarItem {
            content
                .overlay(content: dotUI)
                .drawingGroup()
        } else {
            content
                .overlay(content: dotUI)
        }
    }

    private func dotUI() -> some View {
        ZStack {
            if inAppNotificationsState == .loaded, hasUnreadNotifications {
                Circle()
                    .fill(Color.FigmaMCP.Semantic.accentBrand)
                    .frame(width: dotDimension, height: dotDimension)
                    .shadow(color: .black.opacity(0.3), radius: 2)
                    .offset(x: 7, y: -6)
            }
        }
        .allowsHitTesting(false)
        .animation(.interactiveSpring, value: hasUnreadNotifications)
        .animation(.interactiveSpring, value: inAppNotificationsState)
    }
}

// MARK: - Extension
public extension View {
    func notificationToolbarBadge(isToolbarItem: Bool = true) -> some View {
        self
            .modifier(
                NotificationsBadgeModifier(isToolbarItem: isToolbarItem)
            )
    }
}

// MARK: - Previews
fileprivate
struct PreviewView: View {
    @Shared(.inMemory(.inAppNotificationsState)) var inAppNotificationsState: NotificationLoadingState = .loading
    @Shared(.inMemory(.hasUnreadNotifications)) var hasUnreadNotifications: Bool = true

    var body: some View {
        NavigationStack {
            Text("Content")
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        ToolbarButton(
                            .notifications,
                            background: Color.SemanticV1.backgroundQuaternary,
                            action: {}
                        )
                        .notificationToolbarBadge()
                    }
                }
        }
        .task {
            try? await Task.sleep(for: .seconds(0.5))
            guard !Task.isCancelled else { return }
            $inAppNotificationsState.withLock { $0 = .loaded }
        }
    }
}

#Preview("Dark Mode") {
    PreviewView()
        .preferredColorScheme(.dark)
}

#Preview("Light Mode") {
    PreviewView()
        .preferredColorScheme(.light)
}
