import Foundation
import FirebaseMessaging
import UserNotifications

// MARK: - Notification Service

final class NotificationService: NSObject, @unchecked Sendable {
    static let shared = NotificationService()
    
    private override init() {
        super.init()
    }
    
    func configure() {
        UNUserNotificationCenter.current().delegate = self
        registerForPushNotifications()
    }
    
    private func registerForPushNotifications() {
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in
            guard granted else { return }
            Task { @MainActor in
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }
    
    func updateFCMToken() {
        if let token = Messaging.messaging().fcmToken {
            Task {
                await saveTokenToFirestore(token)
            }
        }
    }
    
    private func saveTokenToFirestore(_ token: String) async {
        guard let userId = try? FirestoreService.shared.userId() else { return }
        
        let tokenRef = FirestoreService.shared.fcmTokensRef(userId).document(token)
        try? await tokenRef.setData([
            "token": token,
            "updatedAt": FieldValue.serverTimestamp()
        ], merge: true)
    }
}

// MARK: - UNUserNotificationCenterDelegate

extension NotificationService: UNUserNotificationCenterDelegate {
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        completionHandler([.banner, .sound])
    }
    
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        // Handle notification tap — deep link to relevant screen
        let userInfo = response.notification.request.content.userInfo
        handleDeepLink(userInfo)
        completionHandler()
    }
    
    private func handleDeepLink(_ userInfo: [AnyHashable: Any]) {
        guard let type = userInfo["type"] as? String else { return }

        switch type {
        case "daily_question", "gentle_reminder", "daily_question_reminder":
            NotificationCenter.default.post(name: .navigateToDailyQuestion, object: nil)
        case "partner_answered":
            NotificationCenter.default.post(name: .navigateToReveal, object: userInfo["questionId"])
        case "streak":
            NotificationCenter.default.post(name: .navigateToHome, object: nil)
        case "partner_started_game", "partner_completed_part", "partner_finished_game":
            NotificationCenter.default.post(name: .navigateToPlay, object: nil)
        case "memory_capsule_unlocked":
            NotificationCenter.default.post(name: .navigateToMemoryLane, object: nil)
        case "challenge_day_ready", "challenge_waiting":
            NotificationCenter.default.post(name: .navigateToConnectionChallenges, object: nil)
        case "chat_message":
            NotificationCenter.default.post(name: .navigateToAnswerHistory, object: nil)
        case "outcome_reminder":
            NotificationCenter.default.post(name: .navigateToSettings, object: nil)
        case "partner_joined", "date_match", "reengagement":
            NotificationCenter.default.post(name: .navigateToHome, object: nil)
        default:
            break
        }
    }
}

// MARK: - Notification Names

extension Notification.Name {
    static let navigateToDailyQuestion = Notification.Name("navigateToDailyQuestion")
    static let navigateToReveal = Notification.Name("navigateToReveal")
    static let navigateToHome = Notification.Name("navigateToHome")
    static let navigateToPlay = Notification.Name("navigateToPlay")
    static let navigateToMemoryLane = Notification.Name("navigateToMemoryLane")
    static let navigateToConnectionChallenges = Notification.Name("navigateToConnectionChallenges")
    static let navigateToAnswerHistory = Notification.Name("navigateToAnswerHistory")
    static let navigateToSettings = Notification.Name("navigateToSettings")
}

typealias FieldValue = FirebaseFirestore.FieldValue