import ForgejoKit
import SwiftUI
import UserNotifications

struct HomeView: View {
    @State private var authService: AuthenticationService?
    @State private var multiInstanceManager: MultiInstanceManager?
    @State private var unreadCount = 0
    @State private var selectedTab = 0
    @Environment(NavigationState.self) private var navigationState

    private let notificationService: NotificationService?
    private var onDisconnectMerged: (() -> Void)?

    init(authService: AuthenticationService) {
        self.authService = authService
        notificationService = authService.client.map { NotificationService(client: $0) }
    }

    init(multiInstanceManager: MultiInstanceManager, onDisconnect: @escaping () -> Void) {
        self.multiInstanceManager = multiInstanceManager
        notificationService = nil
        onDisconnectMerged = onDisconnect
    }

    var body: some View {
        TabView(selection: $selectedTab) {
            Tab("Repositories", systemImage: "folder.fill", value: 0) {
                NavigationStack {
                    if let manager = multiInstanceManager {
                        MergedRepositoryListView(manager: manager)
                    } else if let authService {
                        RepositoryListView(authService: authService)
                    }
                }
            }

            Tab("Issues", systemImage: "exclamationmark.circle.fill", value: 1) {
                NavigationStack {
                    if let manager = multiInstanceManager {
                        MergedIssuesOverviewView(manager: manager)
                    } else if let authService {
                        IssuesOverviewView(authService: authService)
                    }
                }
            }

            Tab("Pull Requests", systemImage: "arrow.triangle.pull", value: 2) {
                NavigationStack {
                    if let manager = multiInstanceManager {
                        MergedPullRequestsOverviewView(manager: manager)
                    } else if let authService {
                        PullRequestsOverviewView(authService: authService)
                    }
                }
            }

            Tab("Notifications", systemImage: "bell.fill", value: 3) {
                NavigationStack {
                    if let manager = multiInstanceManager {
                        MergedNotificationsOverviewView(manager: manager)
                    } else if let authService {
                        NotificationsOverviewView(authService: authService)
                    }
                }
            }
            .badge(unreadCount)

            Tab("Settings", systemImage: "gearshape", value: 4) {
                NavigationStack {
                    if let manager = multiInstanceManager {
                        MergedSettingsTabView(manager: manager, onDisconnect: onDisconnectMerged)
                    } else if let authService {
                        SettingsTabView(authService: authService)
                    }
                }
            }
        }
        .tabBarMinimizeBehavior(.onScrollDown)
        .task {
            await loadUnreadCount()
        }
        .onChange(of: selectedTab) {
            Task { await loadUnreadCount() }
        }
        .onChange(of: navigationState.pendingNavigation) { _, pending in
            guard let pending else { return }
            selectedTab = pending.targetTab
            navigationState.consume()
        }
        .onReceive(NotificationCenter.default.publisher(for: .notificationsDidChange)) { _ in
            Task { await loadUnreadCount() }
        }
    }

    private func loadUnreadCount() async {
        if let multiInstanceManager {
            unreadCount = await multiInstanceManager.totalUnreadCount
        } else if let notificationService {
            do {
                unreadCount = try await notificationService.fetchUnreadCount()
            } catch {
                // Silently ignore, badge is non-critical, keep the prior count
                return
            }
        } else {
            return
        }
        // Mirror the in-app tab badge to the system app icon badge in both modes
        try? await UNUserNotificationCenter.current().setBadgeCount(unreadCount)
    }
}

#if DEBUG
    #Preview {
        HomeView(authService: .previewDefault)
    }
#endif
