import SwiftUI
import UIKit

#if canImport(GoogleMobileAds)
import GoogleMobileAds

struct AdBannerView: View {
    var adUnitId: String = AdMobConfig.resolvedBannerHomeUnitId
    @State private var state: BannerState = .loading

    var body: some View {
        VStack(spacing: 0) {
            Rectangle()
                .fill(Color.mealMoodTextSecondary.opacity(0.22))
                .frame(height: 1)

            ZStack {
                Color.mealMoodSurface

                BannerBridge(adUnitId: adUnitId, state: $state)

                if state != .loaded {
                    HStack(spacing: 6) {
                        Image(systemName: "megaphone")
                        Text(state == .loading ? "ads_loading" : "ads_unavailable")
                            .font(.mealMoodCaption)
                    }
                    .foregroundColor(.mealMoodTextSecondary)
                }
            }
            .frame(height: 56)
            .clipped()
        }
        .frame(maxWidth: .infinity)
        .background(Color.mealMoodSurface)
    }
}

private enum BannerState {
    case loading
    case loaded
    case failed
}

private struct BannerBridge: UIViewRepresentable {
    let adUnitId: String
    @Binding var state: BannerState

    func makeCoordinator() -> Coordinator {
        Coordinator(state: $state)
    }

    func makeUIView(context: Context) -> UIView {
        let container = UIView()
        container.backgroundColor = UIColor(Color.mealMoodSurface)
        container.clipsToBounds = true

        let width = max(UIScreen.main.bounds.width, 320)
        let adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(width)
        let banner = GADBannerView(adSize: adSize)
        banner.adUnitID = adUnitId
        banner.delegate = context.coordinator
        banner.rootViewController = rootViewController()
        banner.translatesAutoresizingMaskIntoConstraints = false
        banner.backgroundColor = .clear
        context.coordinator.bannerView = banner

        container.addSubview(banner)
        NSLayoutConstraint.activate([
            banner.centerXAnchor.constraint(equalTo: container.centerXAnchor),
            banner.centerYAnchor.constraint(equalTo: container.centerYAnchor),
            banner.widthAnchor.constraint(equalToConstant: adSize.size.width),
            banner.heightAnchor.constraint(equalToConstant: adSize.size.height)
        ])

        context.coordinator.loadBannerIfPossible()
        return container
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        context.coordinator.bannerView?.rootViewController = rootViewController()
        context.coordinator.loadBannerIfPossible()
    }

    private func rootViewController() -> UIViewController? {
        UIApplication.shared.connectedScenes
            .compactMap { $0 as? UIWindowScene }
            .flatMap(\.windows)
            .first(where: \.isKeyWindow)?
            .rootViewController
    }

    final class Coordinator: NSObject, GADBannerViewDelegate {
        @Binding var state: BannerState
        weak var bannerView: GADBannerView?
        private var didRequestLoad = false
        private var retryCount = 0

        init(state: Binding<BannerState>) {
            self._state = state
        }

        func loadBannerIfPossible() {
            guard let bannerView, bannerView.rootViewController != nil else { return }
            guard !didRequestLoad else { return }
            didRequestLoad = true
            state = .loading
            bannerView.load(GADRequest())
        }

        func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
            state = .loaded
            retryCount = 0
        }

        func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: any Error) {
            state = .failed
            didRequestLoad = false

            if retryCount < 2 {
                retryCount += 1
                loadBannerIfPossible()
            }

            #if DEBUG
            print("AdMob banner failed (\(retryCount)): \(error.localizedDescription)")
            #endif
        }
    }
}
#else
struct AdBannerView: View {
    var adUnitId: String = AdMobConfig.resolvedBannerHomeUnitId

    var body: some View {
        VStack(spacing: 0) {
            Rectangle()
                .fill(Color.mealMoodTextSecondary.opacity(0.22))
                .frame(height: 1)
            HStack(spacing: 6) {
                Image(systemName: "megaphone")
                Text("ads_unavailable")
                    .font(.mealMoodCaption)
            }
            .foregroundColor(.mealMoodTextSecondary)
            .frame(maxWidth: .infinity, minHeight: 56)
            .background(Color.mealMoodSurface)
        }
        .frame(maxWidth: .infinity)
        .background(Color.mealMoodSurface)
    }
}
#endif
