import StoreKit
import SwiftUI
import Combine

@MainActor
class StoreManager: ObservableObject {
    static let shared = StoreManager()

    @Published private(set) var isPro: Bool = false
    @Published private(set) var product: Product? = nil
    @Published private(set) var purchaseError: String? = nil

    private let productID = "profeatures"
    private var transactionListenerTask: Task<Void, Never>? = nil

    private init() {
        transactionListenerTask = listenForTransactions()
        Task { await loadProduct() }
        Task { await refreshStatus() }
    }

    deinit {
        transactionListenerTask?.cancel()
    }

    // MARK: - Load product

    func loadProduct() async {
        do {
            let products = try await Product.products(for: [productID])
            product = products.first
        } catch {
            // Produkt konnte nicht geladen werden — kein Absturz
        }
    }

    // MARK: - Purchase

    func purchase() async {
        if product == nil { await loadProduct() }
        guard let product else {
            purchaseError = "Produkt konnte nicht geladen werden. Bitte Internetverbindung prüfen."
            return
        }
        purchaseError = nil
        do {
            let result = try await product.purchase()
            switch result {
            case .success(let verification):
                if case .verified(let transaction) = verification {
                    await transaction.finish()
                    await refreshStatus()
                }
            case .userCancelled:
                break
            case .pending:
                break
            @unknown default:
                break
            }
        } catch {
            purchaseError = error.localizedDescription
        }
    }

    // MARK: - Restore

    func restorePurchases() async {
        do {
            try await AppStore.sync()
            await refreshStatus()
        } catch {
            purchaseError = error.localizedDescription
        }
    }

    // MARK: - Status

    func refreshStatus() async {
        for await result in Transaction.currentEntitlements {
            if case .verified(let transaction) = result,
               transaction.productID == productID,
               transaction.revocationDate == nil {
                isPro = true
                return
            }
        }
        isPro = false
    }

    // MARK: - Transaction listener

    private func listenForTransactions() -> Task<Void, Never> {
        Task(priority: .background) {
            for await result in Transaction.updates {
                if case .verified(let transaction) = result {
                    await transaction.finish()
                    await refreshStatus()
                }
            }
        }
    }
}
