import Foundation
import SwiftUI
import Combine
import GoogleMobileAds
import UserMessagingPlatform
import AppTrackingTransparency
import AdSupport

@MainActor
class AdMobService: ObservableObject {
    // MARK: - Published Properties

    @Published var isConsentObtained = false
    @Published var canShowAds = false
    @Published var isLoading = false
    @Published var shouldRequestNonPersonalizedAds = false

    // MARK: - Ad Unit IDs

    // Ad Unit IDs
    #if DEBUG
    static let bannerAdUnitID = "ca-app-pub-3940256099942544/2934735716" // Test ad unit for development
    #else
    static let bannerAdUnitID = "ca-app-pub-1549720748100858/3342431241" // Production ad unit
    #endif

    // MARK: - Initialization

    init() {
        setupResetObserver()
        Task {
            await configureConsentAndRequestAdsIfNeeded()
        }
    }

    // MARK: - Consent Management

    func requestConsent() async {
        await configureConsentAndRequestAdsIfNeeded()
    }

    func presentPrivacyOptions() async {
        guard let root = topViewController() else { return }
        await withCheckedContinuation { continuation in
            ConsentForm.presentPrivacyOptionsForm(from: root) { _ in
                continuation.resume()
            }
        }
        updateConsentState()
    }

    func resetConsent() {
        ConsentInformation.shared.reset()
        UserDefaults.standard.removeObject(forKey: AppConstants.StorageKeys.adConsentObtained)
        isConsentObtained = false
        canShowAds = false
        shouldRequestNonPersonalizedAds = false
    }

    private func setupResetObserver() {
        NotificationCenter.default.addObserver(
            forName: .didResetData,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            guard let self else { return }
            Task { @MainActor in
                self.resetConsent()
                await self.configureConsentAndRequestAdsIfNeeded()
            }
        }
    }

    private func configureConsentAndRequestAdsIfNeeded() async {
        isLoading = true
        let parameters = RequestParameters()
        await withCheckedContinuation { continuation in
            ConsentInformation.shared.requestConsentInfoUpdate(with: parameters) { _ in
                continuation.resume()
            }
        }

        if let root = topViewController() {
            await withCheckedContinuation { continuation in
                ConsentForm.loadAndPresentIfRequired(from: root) { _ in
                    continuation.resume()
                }
            }
        }

        updateConsentState()
        if canShowAds {
            await requestTrackingIfNeeded()
            updateConsentState()
        }
        isLoading = false
    }

    private func updateConsentState() {
        let consentInfo = ConsentInformation.shared
        canShowAds = consentInfo.canRequestAds
        isConsentObtained = consentInfo.consentStatus == .obtained || consentInfo.consentStatus == .notRequired

        let trackingDenied: Bool
        if #available(iOS 14.5, *) {
            trackingDenied = ATTrackingManager.trackingAuthorizationStatus != .authorized
        } else {
            trackingDenied = false
        }

        shouldRequestNonPersonalizedAds = !isConsentObtained || trackingDenied
        UserDefaults.standard.set(isConsentObtained, forKey: AppConstants.StorageKeys.adConsentObtained)
    }

    private func requestTrackingIfNeeded() async {
        if #available(iOS 14.5, *) {
            _ = await ATTrackingManager.requestTrackingAuthorization()
        }
    }

    private func topViewController() -> UIViewController? {
        guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
              let root = scene.windows.first?.rootViewController else {
            return nil
        }
        var current = root
        while let presented = current.presentedViewController {
            current = presented
        }
        return current
    }

    // MARK: - Analytics

    func logAdImpression() {
        FirebaseService.shared.logAdImpression(adType: "banner")
    }

    func logAdClick() {
        FirebaseService.shared.logAdClick(adType: "banner")
    }
}

// MARK: - Banner Ad Coordinator

class BannerAdCoordinator: NSObject, BannerViewDelegate {
    weak var adMobService: AdMobService?

    func bannerViewDidReceiveAd(_ bannerView: BannerView) {
        print("Banner ad received")
        adMobService?.logAdImpression()
    }

    func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
        print("Banner ad failed to load: \(error.localizedDescription)")
    }

    func bannerViewDidRecordImpression(_ bannerView: BannerView) {
        // Impression recorded
    }

    func bannerViewDidRecordClick(_ bannerView: BannerView) {
        adMobService?.logAdClick()
    }

    func bannerViewWillPresentScreen(_ bannerView: BannerView) {
        // Ad will present full screen
    }

    func bannerViewWillDismissScreen(_ bannerView: BannerView) {
        // Ad will dismiss
    }

    func bannerViewDidDismissScreen(_ bannerView: BannerView) {
        // Ad dismissed
    }
}

// MARK: - UIKit Banner View Wrapper

struct BannerAdView: UIViewRepresentable {
    @EnvironmentObject var adMobService: AdMobService

    func makeUIView(context: Context) -> BannerView {
        let bannerView = BannerView(adSize: AdSizeBanner)
        bannerView.adUnitID = AdMobService.bannerAdUnitID

        // Get root view controller
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let rootViewController = windowScene.windows.first?.rootViewController {
            bannerView.rootViewController = rootViewController
        }

        bannerView.delegate = context.coordinator
        let request = Request()
        if adMobService.shouldRequestNonPersonalizedAds {
            let extras = Extras()
            extras.additionalParameters = ["npa": "1"]
            request.register(extras)
        }
        bannerView.load(request)

        return bannerView
    }

    func updateUIView(_ uiView: BannerView, context: Context) {
        // Banner updates automatically
    }

    func makeCoordinator() -> BannerAdCoordinator {
        let coordinator = BannerAdCoordinator()
        coordinator.adMobService = adMobService
        return coordinator
    }
}
