import SwiftUI
import StoreKit

// MARK: - DonationSectionView

/// The "Support BookStax" section embedded in SettingsView.
/// Shows real products fetched from App Store Connect. Never displays
/// placeholder content — all states (loading, empty, error) are explicit.
struct DonationSectionView: View {
    @State private var service = DonationService.shared

    var body: some View {
        Section {
            sectionContent
        } header: {
            Text(L("settings.donate"))
        } footer: {
            sectionFooter
        }
        .task { await service.loadProducts() }
    }

    // MARK: - Content

    @ViewBuilder
    private var sectionContent: some View {
        switch service.loadState {
        case .loading:
            loadingRow

        case .loaded(let products):
            ForEach(products, id: \.id) { product in
                DonationProductRow(product: product, service: service)
            }

        case .empty:
            Text(L("settings.donate.empty"))
                .foregroundStyle(.secondary)
                .font(.subheadline)

        case .failed:
            HStack {
                Label(L("settings.donate.error"), systemImage: "exclamationmark.triangle")
                    .foregroundStyle(.secondary)
                    .font(.subheadline)
                Spacer()
                Button(L("common.retry")) {
                    Task { await service.loadProducts() }
                }
                .buttonStyle(.borderless)
                .foregroundStyle(.tint)
            }
        }
    }

    private var loadingRow: some View {
        HStack {
            Text(L("settings.donate.loading"))
                .foregroundStyle(.secondary)
            Spacer()
            ProgressView()
                .controlSize(.small)
        }
    }

    @ViewBuilder
    private var sectionFooter: some View {
        if case .failed = service.loadState {
            EmptyView()
        } else {
            Text(L("settings.donate.footer"))
        }
    }
}

// MARK: - DonationProductRow

private struct DonationProductRow: View {
    let product: Product
    let service: DonationService

    private var isPurchasing: Bool {
        service.purchaseState.activePurchasingID == product.id
    }
    private var isAnyPurchaseInProgress: Bool {
        service.purchaseState.activePurchasingID != nil
    }
    private var isThankYou: Bool {
        service.purchaseState.thankYouID == product.id
    }
    private var isPending: Bool {
        service.purchaseState.pendingID == product.id
    }
    private var errorMessage: String? {
        service.purchaseState.errorMessage(for: product.id)
    }
    private var lastDonatedDate: Date? {
        service.donationHistory[product.id]
    }
    private var isDisabled: Bool {
        isAnyPurchaseInProgress || isPending
    }

    var body: some View {
        Button {
            guard !isDisabled else { return }
            if errorMessage != nil {
                service.dismissError(for: product.id)
            } else {
                Task { await service.purchase(product) }
            }
        } label: {
            HStack(spacing: 12) {
                productInfo
                Spacer()
                trailingIndicator
            }
        }
        .disabled(isDisabled)
    }

    // MARK: - Subviews

    private var productInfo: some View {
        VStack(alignment: .leading, spacing: 3) {
            Text(product.displayName)
                .foregroundStyle(.primary)

            if let date = lastDonatedDate {
                Text(String(format: L("settings.donate.donated.on"),
                            date.formatted(date: .abbreviated, time: .omitted)))
                    .font(.caption)
                    .foregroundStyle(.pink)
            }

            if isPending {
                Text(L("settings.donate.pending"))
                    .font(.caption)
                    .foregroundStyle(.orange)
            }

            if let message = errorMessage {
                Text(message)
                    .font(.caption)
                    .foregroundStyle(.red)
            }
        }
    }

    @ViewBuilder
    private var trailingIndicator: some View {
        if isPurchasing {
            ProgressView()
                .controlSize(.small)
        } else if isThankYou {
            Image(systemName: "heart.fill")
                .foregroundStyle(.pink)
        } else if errorMessage != nil {
            Image(systemName: "arrow.counterclockwise")
                .foregroundStyle(.secondary)
        } else {
            Text(product.displayPrice)
                .foregroundStyle(.tint)
                .bold()
                .monospacedDigit()
        }
    }
}
