import SwiftUI

/**
 * In-App Message Banner — SwiftUI component for top/bottom banner display.
 * Part of ByteLystPlatformSDK.
 */
@available(iOS 15.0, *)
public struct BLInAppMessageBanner: View {
    @ObservedObject var client: BLBroadcastClient
    @State private var messages: [BLInAppMessage] = []
    @State private var unreadCount = 0
    
    let position: BannerPosition
    
    public enum BannerPosition {
        case top, bottom
    }
    
    public init(client: BLBroadcastClient, position: BannerPosition = .top) {
        self.client = client
        self.position = position
    }
    
    public var body: some View {
        VStack(spacing: 8) {
            ForEach(messages.filter { $0.status == .unread && ($0.style == .banner || $0.style == .toast) }) { message in
                BannerCard(
                    message: message,
                    onDismiss: { await dismissMessage(message) },
                    onTap: { await handleTap(message) }
                )
            }
        }
        .padding(.horizontal)
        .padding(position == .top ? .top : .bottom, 8)
        .task {
            await loadMessages()
            startPolling()
        }
    }
    
    private func loadMessages() async {
        do {
            messages = try await client.listMessages()
            unreadCount = messages.filter { $0.status == .unread }.count
        } catch {
            // Silently ignore load errors
        }
    }
    
    private func startPolling() {
        client.startPolling(interval: 60) { updatedMessages in
            self.messages = updatedMessages
            self.unreadCount = updatedMessages.filter { $0.status == .unread }.count
        }
    }
    
    private func dismissMessage(_ message: BLInAppMessage) async {
        try? await client.markDismissed(messageId: message.id)
        messages.removeAll { $0.id == message.id }
    }
    
    private func handleTap(_ message: BLInAppMessage) async {
        _ = try? await client.trackClick(messageId: message.id)
        if let urlString = message.ctaUrl, let url = URL(string: urlString) {
            await UIApplication.shared.open(url)
        }
        try? await client.markRead(messageId: message.id)
        if let index = messages.firstIndex(where: { $0.id == message.id }) {
            messages[index] = message // refresh from next poll
        }
    }
}

@available(iOS 15.0, *)
struct BannerCard: View {
    let message: BLInAppMessage
    let onDismiss: () async -> Void
    let onTap: () async -> Void
    
    var body: some View {
        HStack(alignment: .top, spacing: 12) {
            VStack(alignment: .leading, spacing: 4) {
                Text(message.title)
                    .font(.headline)
                
                if !message.body.isEmpty {
                    Text(message.body)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .lineLimit(2)
                }
                
                if message.ctaText != nil {
                    Text("Tap to open")
                        .font(.caption)
                        .foregroundColor(.blue)
                }
            }
            
            Spacer()
            
            if message.dismissible {
                Button(action: { Task { await onDismiss() } }) {
                    Image(systemName: "xmark")
                        .foregroundColor(.secondary)
                        .padding(8)
                }
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 12)
                .fill(backgroundColor)
                .shadow(radius: 2)
        )
        .contentShape(Rectangle())
        .onTapGesture {
            Task { await onTap() }
        }
    }
    
    private var backgroundColor: Color {
        switch message.priority {
        case .urgent:
            return Color.red.opacity(0.1)
        case .high:
            return Color.orange.opacity(0.1)
        default:
            return Color(.systemBackground)
        }
    }
}

@available(iOS 15.0, *)
public struct BLBroadcastModal: View {
    @ObservedObject var client: BLBroadcastClient
    @State private var currentMessage: BLInAppMessage?
    @State private var isPresented = false
    
    public init(client: BLBroadcastClient) {
        self.client = client
    }
    
    public var body: some View {
        EmptyView()
            .sheet(isPresented: $isPresented) {
                if let message = currentMessage {
                    ModalContent(
                        message: message,
                        onDismiss: { await dismissMessage() },
                        onAction: { await handleAction() }
                    )
                }
            }
            .task {
                startPolling()
            }
    }
    
    private func startPolling() {
        client.startPolling(interval: 30) { messages in
            let modalMessages = messages.filter {
                $0.status == .unread && ($0.style == .modal || $0.style == .fullscreen)
            }
            if let first = modalMessages.first, self.currentMessage == nil {
                self.currentMessage = first
                self.isPresented = true
            }
        }
    }
    
    private func dismissMessage() async {
        if let message = currentMessage {
            try? await client.markDismissed(messageId: message.id)
        }
        isPresented = false
        currentMessage = nil
    }
    
    private func handleAction() async {
        if let message = currentMessage {
            _ = try? await client.trackClick(messageId: message.id)
            if let urlString = message.ctaUrl, let url = URL(string: urlString) {
                await UIApplication.shared.open(url)
            }
            try? await client.markRead(messageId: message.id)
        }
        isPresented = false
        currentMessage = nil
    }
}

@available(iOS 15.0, *)
struct ModalContent: View {
    let message: BLInAppMessage
    let onDismiss: () async -> Void
    let onAction: () async -> Void
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 20) {
                    Text(message.title)
                        .font(.title2.bold())
                    
                    if !message.body.isEmpty {
                        Text(message.body)
                            .font(.body)
                            .foregroundColor(.secondary)
                            .multilineTextAlignment(.center)
                    }
                    
                    if message.ctaText != nil {
                        Button(action: { Task { await onAction() } }) {
                            Text(message.ctaText!)
                                .font(.headline)
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding()
                                .background(Color.blue)
                                .cornerRadius(12)
                        }
                    }
                }
                .padding()
            }
            .navigationBarItems(
                trailing: message.dismissible ? Button("Close") {
                    Task { await onDismiss() }
                } : nil
            )
        }
    }
}
