import Adamantium
import APIClient
import BackendEnvironmentClient
import Charts
import ComponentLibrary
import ComposableArchitecture
import FeatureBrandedAlert
import FeatureToasts
import FeatureTopUp
import Foundation
import Localization
import NavigationRouterClient
import PaywallClient
import StatsigClient
import StoreKit
import SwiftUI
import Utilities

// swiftlint:disable file_length

@Reducer
public struct PaywallLoaded {
    @Reducer(state: .equatable)
    public enum Destination {
        case topUp(TopUp)
        case brandedAlert(BrandedAlert)
    }

    @ObservableState
    public struct State: Equatable {
        var isTopUpsEnabled: Bool {
            FeatureFlag.legacy.topUps
        }

        var showSubscriptionDiscounts: Bool {
            FeatureFlag.legacy.subscriptionDiscounts
        }

        var annualPlanDiscountPercentage: Int? {
            let value = FeatureFlag.legacy.annualPlanDiscountPercentage
            guard value > 0 else { return nil }
            return value
        }

        var monthlyPlanDiscountPercentage: Int? {
            let value = FeatureFlag.legacy.monthlyPlanDiscountPercentage
            guard value > 0 else { return nil }
            return value
        }

        var isV5Launch: Bool {
            FeatureFlag.legacy.v5Launch == true
        }

        @Presents public var destination: Destination.State?
        let subscriptions: [Subscription]
        let appStoreCurrencyCode: String?
        var purchases: [Entitlement]
        var billingInfo: SubscriptionInfoResponse
        var purchasing: Subscription?

        var songsLeft: Int {
            billingInfo.songsLeft
        }

        var showSongCountAndTopUp: Bool {
            return isSubscribed && isTopUpsEnabled
        }

        var isSubscribed: Bool {
            return !purchases.isEmpty || billingInfo.plan != nil
        }

        var upsellAvailable: Bool {
            let isMobilePremierAnnual = purchases.contains(where: { $0.plan == .premier && $0.period == .year })
            let isWebPremierAnnual = billingInfo.plan?.level == 30 && billingInfo.period == "year" // Premium Annual
            let isPremierAnnual = isMobilePremierAnnual || isWebPremierAnnual
            return !isPremierAnnual
        }
    }

    public enum Action {
        case destination(PresentationAction<Destination.Action>)

        case viewDidAppear

        case purchase(Subscription)
        case purchaseResult(Result<(Subscription, [Entitlement]), Error>)
        case topUpTapped
        case delegate(Delegate)
        case openAppStoreSubscriptions
        case cancelTapped

        public enum Delegate {
            case refreshCreditsAfter
        }
    }

    @Dependency(\.openURL) var openURL
    @Dependency(\.telemetryClient) var telemetry
    @Dependency(PaywallClient.self) private var paywall
    @Dependency(StatsigClient.self) private var statsigClient
    @Dependency(NavigationRouterClient.self) private var navigationRouter
    @Dependency(\.toastClient.show) var showToast

    private func showManageSubscriptions() async {
        guard let windowScene = await UIWindow.current?.windowScene else {
            log.telemetry.assertionFailure("Failed to get window scene for showing subscriptions")
            return
        }

        do {
            try await AppStore.showManageSubscriptions(in: windowScene)
        } catch {
            log.telemetry.error(error, message: "Failed to show manage subscriptions.")
        }
    }

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .purchase(let subscription):
                if state.billingInfo.subscriptionPlatform == "stripe" {
                    let baseUrl = BackendEnvironmentProvider.currentConfiguration().webEndpointHost
                    let url = URL(string: "https://\(baseUrl)/account")!
                    return .run { _ in
                        await openURL(url)
                    }
                } else {
                    state.purchasing = subscription
                    return .run { [upsellAvailable = state.upsellAvailable] send in
                        await send(.purchaseResult(Result(catching: {
                            let entitlements = try await paywall.purchase(subscription, upsellAvailable)
                            return (subscription, entitlements)
                        })))
                    }
                }

            case .purchaseResult(.success((_, let entitlements))):
                state.purchasing = nil
                state.purchases = entitlements
                return .none

            case .purchaseResult(.failure(PaywallError.cancelled)):
                state.purchasing = nil
                return .none

            case .purchaseResult(.failure(let error)):
                log.telemetry.error(error)
                return .none

            case .topUpTapped:
                state.destination = .topUp(.init())
                return .none

            case .destination(.presented(.topUp(.delegate(.toastAfter(let toast))))):
                showToast(toast)
                return .none

            case .destination(.presented(.topUp(.delegate(.refreshCreditsAfter)))):
                return .send(.delegate(.refreshCreditsAfter))

            case .destination(.presented(.topUp(.delegate(.setBillingInfoAfter(let billingInfo))))):
                state.billingInfo = billingInfo
                return .none

            case .destination, .delegate, .viewDidAppear:
                return .none

            case .openAppStoreSubscriptions:
                return .run { send in
                    await showManageSubscriptions()
                    await send(.destination(.dismiss))
                }

            case .cancelTapped:
                state.destination = .brandedAlert(.init())
                return .none
            }
        }
        .ifLet(\.$destination, action: \.destination)

        Analytics()
    }
}

public struct PaywallLoadedView: View {
    @Bindable var store: StoreOf<PaywallLoaded>
    @State private var selectedPeriod: Subscription.Period = .year
    // Made this one for all since exapnding each one is annoying
    @State private var isSeeMoreExpanded: Bool = false
    @ObservedObject var circleMaskedAuraCoordinator = CircleMaskedAuraView.Coordinator()

    public var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                creditBalance

                if store.showSongCountAndTopUp {
                    topUpRow
                }

                Divider()
                    .overlay(Color.SemanticV1.borderPrimary)
                    .environment(\.colorScheme, .dark)

                discount

                planList

                footer
            }
            .padding(.horizontal, 12)
            .padding(.vertical, 16)
        }
        .background {
            if store.showSubscriptionDiscounts && store.upsellAvailable {
                auraBackground
                    .ignoresSafeArea()
            } else {
                specklyBackground
                    .ignoresSafeArea()
            }
        }
        .background(store.upsellAvailable ? Color(red: 0.05, green: 0.03, blue: 0.03) : Color.SemanticV1.backgroundPrimary)
        .navigationDestination(item: $store.scope(state: \.destination?.topUp, action: \.destination.topUp)) { topUpStore in
            TopUpScreen(store: topUpStore)
                .customBackButton(background: Material.ultraThin, action: { store.send(.destination(.dismiss)) })
        }
        .brandedAlert(
            item: $store.scope(state: \.destination?.brandedAlert, action: \.destination.brandedAlert),
            style: .custom(MultiButtonAlertStyle.TextCopy(
                title: L10n.FeaturePaywall.cancelPlanTitle,
                description: L10n.FeaturePaywall.cancelPlanDescription,
                primaryButtonLabel: L10n.FeaturePaywall.cancelSubscription,
                secondaryButtonLabel: L10n.FeaturePaywall.cancelPlanDismiss
            )),
            primaryButtonTapped: { store.send(.openAppStoreSubscriptions) },
            secondaryButtonTapped: { store.send(.destination(.dismiss)) }
        )
        .onAppear {
            store.send(.viewDidAppear)
        }
    }

    @ViewBuilder
    var auraBackground: some View {
        #if targetEnvironment(simulator)
            Color.black
        #else
            CircleMaskedAuraView(
                circleMaskedAuraCoordinator,
                morphSpeed: 0.013,
                scale: 2.0
            )
            .onAppear { applyAuraBackgroundPropertyTarget() }
        #endif
    }

    private func applyAuraBackgroundPropertyTarget() {
        let propertyTarget = CircleMaskedAuraView.Coordinator.PropertyTarget(
            mainColorA: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            mainColorB: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            mainColorC: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            darkColorA: .init(x: 0.05490195, y: 0.05490195, z: 0.05490195),
            darkColorB: .init(x: 0.07673397, y: 0.07673397, z: 0.07673397),
            darkColorC: .init(x: 0.117168404, y: 0.117168404, z: 0.117168404),
            maskPosX: 0.453,
            maskPosY: 0.928,
            maskEdgeFade: 0.661,
            maskMinValueScalar: 0.0,
            maskRadius: 0.4
        )

        circleMaskedAuraCoordinator.setGradientSeed(.zero)
        circleMaskedAuraCoordinator.applyPropertiesWithoutTransitionAnimation(propertyTarget)
        circleMaskedAuraCoordinator.setPropertyTarget(propertyTarget)
    }

    @ViewBuilder
    private var discount: some View {
        VStack(spacing: 12) {
            // Toogle year/month
            HStack(spacing: 8) {
                HStack {
                    Spacer()
                    monthlyLabel
                }

                Toggle("", isOn: Binding(
                    get: { selectedPeriod == .year },
                    set: { selectedPeriod = $0 ? .year : .month }
                ))
                .labelsHidden()
                .scaleEffect(0.8)
                .tint(.SemanticV1.iconLink)

                HStack {
                    annuallyLabel
                    Spacer()
                }
            }
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .environment(\.colorScheme, .dark)
        .onTapGesture { selectedPeriod = selectedPeriod == .month ? .year : .month }
    }

    @ViewBuilder
    var monthlyLabel: some View {
        if let monthlyPlanDiscountPercentage = store.monthlyPlanDiscountPercentage,
           selectedPeriod == .month, store.upsellAvailable
        {
            Text(L10n.FeaturePaywall.monthlyBillingOff(String(monthlyPlanDiscountPercentage)))
                .typographyV1(.body1)
                .opacity(selectedPeriod == .year ? 0.4 : 1.0)
        } else {
            Text(L10n.FeaturePaywall.monthlyBilling)
                .typographyV1(.body1)
                .opacity(selectedPeriod == .year ? 0.4 : 1.0)
        }
    }

    var annuallyLabel: some View {
        if let annualPlanDiscountPercentage = store.annualPlanDiscountPercentage, selectedPeriod == .year, store.upsellAvailable {
            Text(L10n.FeaturePaywall.annualBillingOff(String(annualPlanDiscountPercentage)))
                .typographyV1(.body1)
                .opacity(selectedPeriod == .month ? 0.4 : 1.0)
        } else {
            Text(L10n.FeaturePaywall.annualBilling)
                .typographyV1(.body1)
                .opacity(selectedPeriod == .month ? 0.4 : 1.0)
        }
    }

    @ViewBuilder
    private var creditBalance: some View {
        VStack(spacing: -4) {
            Text(store.billingInfo.totalCreditsLeft.formatted())
                .typographyV1(.totalCreditsLeft)

            if store.isSubscribed {
                // Paid user
                Text(L10n.FeaturePaywall.songsLeftThisMonth(store.billingInfo.songsLeft))
                    .typographyV1(.body1)
            } else {
                // Free user
                Text(L10n.FeatureSettings.songsLeftToday(store.billingInfo.songsLeft))
                    .typographyV1(.body1)
            }
        }
        .foregroundColor(Color.SemanticV1.textPrimary)
        .environment(\.colorScheme, .dark)
        .frame(alignment: .center)
        .padding(.bottom, 8)
        .padding(.horizontal, 32)
    }

    @ViewBuilder
    private var topUpRow: some View {
        Button {
            store.send(.topUpTapped)
        } label: {
            Text(L10n.FeaturePaywall.topUpCta)
                .typographyV1(.body1)
                .padding(.top, 6)
                .padding(.bottom, 8)
                .padding(.horizontal, 16)
                .background(Color.SemanticV1.backgroundSecondary)
                .clipShape(RoundedRectangle(cornerRadius: 8))
        }
        .buttonStyle(ScaleButtonStyle())
        .padding(.horizontal, 32)
        .padding(.bottom, 6)
    }

    @ViewBuilder
    private var planList: some View {
        VStack(spacing: 16) {
            let filtered = store.subscriptions
                .filter { $0.period == selectedPeriod }
                .sorted(by: { $0.semanticPlan.rawValue < $1.semanticPlan.rawValue })

            ForEach(filtered) { subscription in
                subscriptionCard(subscription, store.billingInfo, store.purchases, store.purchasing, store.isV5Launch)
            }
        }
        .frame(maxWidth: .infinity)
        .padding(.bottom, 42)
    }

    @ViewBuilder
    private var footer: some View {
        VStack(spacing: 0) {
            let baseUrl = BackendEnvironmentProvider.currentConfiguration().webEndpointHost
            let terms = L10n.FeaturePaywall.terms(baseUrl, baseUrl)

            (
                Text(LocalizedStringKey(L10n.FeaturePaywall.needMore))
                    + Text(" ")
                    + Text(LocalizedStringKey(L10n.FeaturePaywall.contactUs))
            )
            .typographyV1(.body2)
            .multilineTextAlignment(.center)
            .foregroundStyle(Color.SemanticV1.textPrimary)
            .tint(.SemanticV1.textLink)

            Text(LocalizedStringKey(terms))
                .typographyV1(.body2)
                .multilineTextAlignment(.center)
                .foregroundStyle(Color.SemanticV1.textPrimary)
                .tint(.SemanticV1.textLink)
        }
        .safePadding()
    }

    @ViewBuilder
    private var specklyBackground: some View {
        VStack {
            Rectangle()
                .foregroundColor(.clear)
                .background {
                    ZStack {
                        Color.SemanticV1.backgroundPrimary

                        Circle()
                            .fill(Color(red: 242 / 255, green: 64 / 255, blue: 24 / 255))
                            .frame(width: 200)
                            .blur(radius: 106)
                            .offset(x: 100, y: 130)

                        Circle()
                            .fill(Color(red: 225 / 255, green: 177 / 255, blue: 248 / 255, opacity: 0.5))
                            .frame(width: 200)
                            .blur(radius: 106)
                            .offset(x: -160, y: -160)

                        Circle()
                            .fill(Color(red: 16 / 255, green: 0 / 255, blue: 192 / 255))
                            .frame(width: 200)
                            .blur(radius: 106)
                            .offset(x: -160, y: 160)

                        Image.Assets.noise
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .opacity(0.25)
                    }
                }
                .environment(\.colorScheme, .dark)
                .frame(height: store.showSongCountAndTopUp ? 420 : 360)

            Rectangle()
                .fill(Color.SemanticV1.backgroundPrimary)
        }
    }

    @ViewBuilder
    private func subscriptionCard(
        _ subscription: Subscription,
        _ billingInfo: SubscriptionInfoResponse,
        _ purchases: [Entitlement],
        _ purchasing: Subscription?,
        _ isV5Launch: Bool
    ) -> some View {
        let isSubscribed: Bool = {
            guard billingInfo.subscriptionPlatform == "stripe" else {
                return purchases.contains(where: { entitlement in
                    entitlement.period == subscription.period && entitlement.plan == subscription.semanticPlan
                })
            }
            guard let plan = billingInfo.plan else { return false }
            return subscription.semanticPlan == .pro &&
                ((plan.level == 10 && subscription.period == .month) ||
                    (plan.level == 30 && subscription.period == .month))
        }()

        let downgradeUnavailable: Bool = {
            var yearlySubscriptions = 0
            for entitlement in purchases {
                if entitlement.period == .year { yearlySubscriptions += 1 }
            }
            return yearlySubscriptions > 0 && subscription.period == .month
        }()

        let subscriptionInfo = getSubscriptionInfo(for: subscription.id, isV5Launch: isV5Launch)

        SubscriptionCardView(
            isSeeMoreExpanded: $isSeeMoreExpanded,
            subscription: subscription,
            appStoreCurrencyCode: store.appStoreCurrencyCode,
            info: subscriptionInfo,
            downgradeUnavailable: downgradeUnavailable,
            isSubscribed: isSubscribed,
            isLoading: purchasing == subscription,
            showExternal: billingInfo.subscriptionPlatform == "stripe",
            showMostPopular: subscription.semanticPlan == .pro,
            showBestValue: subscription.semanticPlan == .premier,
            upsellAvailable: store.upsellAvailable
        ) {
            store.send(isSubscribed ? .cancelTapped : .purchase(subscription))
        }
    }
}

struct SubscriptionCardView: View {
    @Binding var isSeeMoreExpanded: Bool

    let subscription: Subscription
    let appStoreCurrencyCode: String?
    var info: [(Bool, String)]
    let downgradeUnavailable: Bool
    let isSubscribed: Bool
    let isLoading: Bool
    let showExternal: Bool
    let showMostPopular: Bool
    let showBestValue: Bool
    let upsellAvailable: Bool
    let action: () -> Void

    private let priceFormatter: NumberFormatter

    init(
        isSeeMoreExpanded: Binding<Bool>,
        subscription: Subscription,
        appStoreCurrencyCode: String?,
        info: [(Bool, String)],
        downgradeUnavailable: Bool,
        isSubscribed: Bool,
        isLoading: Bool,
        showExternal: Bool,
        showMostPopular: Bool,
        showBestValue: Bool,
        upsellAvailable: Bool,
        action: @escaping () -> Void
    ) {
        self._isSeeMoreExpanded = isSeeMoreExpanded
        self.subscription = subscription
        self.appStoreCurrencyCode = appStoreCurrencyCode
        self.info = info
        self.downgradeUnavailable = downgradeUnavailable
        self.isSubscribed = isSubscribed
        self.isLoading = isLoading
        self.showExternal = showExternal
        self.showMostPopular = showMostPopular
        self.showBestValue = showBestValue
        self.upsellAvailable = upsellAvailable
        self.action = action

        // Add annual savings info if applicable
        if upsellAvailable,
           subscription.period == .year,
           let yearPrice = subscription.yearPrice,
           let discountYearPrice = subscription.discountYearPrice,
           discountYearPrice < yearPrice
        {
            let saving = yearPrice - discountYearPrice
            let formatted = saving.formatted(
                .currency(code: appStoreCurrencyCode ?? subscription.currencyCode ?? Locale.current.currency?.identifier ?? "USD")
                    .locale(.autoupdatingCurrent)
                    .presentation(.narrow)
                    .precision(.fractionLength(2))
            )

            self.info.insert(
                (true, L10n.FeaturePaywall.saveOnAnnual(formatted)),
                at: 0
            )
        }

        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencyCode = appStoreCurrencyCode ?? subscription.currencyCode ?? "USD"
        self.priceFormatter = formatter
    }

    private func formatPrice(_ price: Double) -> String {
        if let formatted = priceFormatter.string(from: NSNumber(value: price)) {
            if priceFormatter.currencyCode == "USD" {
                return formatted.replacingOccurrences(of: ".00", with: "")
            }
            return formatted
        }
        return String(format: "%.2f", price)
    }

    private var priceString: String {
        // When discount is available, show discount price as main price
        if let discountPrice = subscription.discountPrice, upsellAvailable {
            return formatPrice(discountPrice)
        }
        return formatPrice(subscription.price)
    }

    private var strikethroughPriceString: String? {
        guard upsellAvailable,
              subscription.discountPrice != nil else {
            return nil
        }
        // Show regular price as strikethrough when discount is available
        return formatPrice(subscription.price)
    }

    private var yearPriceString: String? {
        if subscription.period == .year {
            if let discountYearPrice = subscription.discountYearPrice, upsellAvailable {
                return formatPrice(discountYearPrice)
            } else if let yearPrice = subscription.yearPrice {
                return formatPrice(yearPrice)
            }
        }
        return nil
    }

    private var buttonTitle: String {
        if downgradeUnavailable {
            return L10n.FeaturePaywall.downgradeUnavailable
        } else if isSubscribed {
            return L10n.FeaturePaywall.cancelPlan
        } else {
            return L10n.FeaturePaywall.selectPlan
        }
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            VStack(spacing: .zero) {
                HStack(spacing: 8) {
                    Text(subscription.semanticPlan.title)
                        .typographyV1(.headline3.editorialNewLight())
                        .foregroundColor(Color.SemanticV1.textPrimary)
                        .scaledToFit()
                        .minimumScaleFactor(0.7)

                    Spacer()

                    HStack(spacing: 4) {
                        if let strikethroughPriceString, !strikethroughPriceString.isEmpty, upsellAvailable {
                            Text(strikethroughPriceString)
                                .typographyV1(.strikethroughPrice)
                                .foregroundStyle(Color.SemanticV1.textTertiary)
                                .strikethrough()
                                .lineLimit(1)
                                .fixedSize()
                        }

                        Text(priceString)
                            .typographyV1(.headline3.editorialNewLight())
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                            .lineLimit(1)
                            .fixedSize()

                        Text("/\(Subscription.Period.month.title.capitalized)")
                            .typographyV1(.body1)
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                            .lineLimit(1)
                            .fixedSize()
                    }
                }
                .padding(.horizontal, 18)

                if subscription.period == .year {
                    HStack(spacing: .zero) {
                        Spacer()

                        if let yearPriceString {
                            Text(L10n.FeaturePaywall.billedAnnually(yearPriceString))
                                .typographyV1(.body3.ppNeueMontrealBook())
                                .foregroundStyle(Color.SemanticV1.textPrimary)
                                .lineLimit(1)
                                .padding(.trailing, 2.0)
                        }
                    }
                    .padding(.horizontal, 18)
                } else if subscription.period == .month {
                    HStack {
                        Spacer()

                        Text(L10n.FeaturePaywall.billedMonthly)
                            .typographyV1(.body3.ppNeueMontrealBook())
                            .foregroundStyle(Color.SemanticV1.textPrimary)
                            .lineLimit(1)
                    }
                    .padding(.horizontal, 18)
                }
            }

            VStack(spacing: 8) {
                if showMostPopular {
                    mostPopular
                } else if showBestValue {
                    bestValue
                }

                ForEach(isSeeMoreExpanded ? info : info.prefix(upTo: 2).map { $0 }, id: \.1) { imageCheck, text in
                    HStack(spacing: 4) {
                        if imageCheck {
                            Image(systemName: "checkmark.circle.fill")
                                .font(.system(size: 10.0, weight: .bold))
                                .foregroundStyle(Color.SemanticV1.iconLink)
                        } else {
                            Image(systemName: "xmark.circle.fill")
                                .font(.system(size: 10.0, weight: .bold))
                                .foregroundStyle(Color.SemanticV1.iconSecondary)
                        }

                        Text(text)
                            .typographyV1(.body1)
                            .foregroundColor(Color.SemanticV1.textPrimary)

                        Spacer()
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                }

                if !isSeeMoreExpanded {
                    Button {
                        isSeeMoreExpanded = true
                    } label: {
                        HStack(spacing: 4) {
                            Image(systemName: "chevron.down")
                                .font(.system(size: 14.0, weight: .bold))

                            Text(L10n.FeaturePaywall.more)
                                .typographyV1(.body1)

                            Spacer()
                        }
                        .foregroundStyle(Color.SemanticV1.textPrimary)
                    }
                }

                Spacer()
                PrimaryButtonV1(
                    title: buttonTitle,
                    isLoading: isLoading,
                    colorCombination: isSubscribed ? .secondary : .dark,
                    leadingView: {
                        if showExternal {
                            Image.Icon.arrowUp.foregroundColor(.SemanticV1.textInvert)
                        }
                    },
                    action: action
                )
                .pillButtonSizeV1(.medium)
                .disabled(downgradeUnavailable)

                if downgradeUnavailable {
                    Text(L10n.FeaturePaywall.downgradeMessage)
                        .inlineTypographyV1(.caption3.neueMontrealRegular())
                        .foregroundColor(.SemanticV1.textSecondary)
                        .multilineTextAlignment(.center)
                        .fixedSize(horizontal: false, vertical: true)
                }
            }
            .padding(.horizontal, 18)
        }
        .frame(maxWidth: .infinity)
        .padding(.vertical, 18)
        .background(Color.SemanticV1.backgroundSecondary)
        .clipShape(.rect(cornerRadius: 24))
    }

    @ViewBuilder
    private var mostPopular: some View {
        HStack {
            Text(L10n.FeaturePaywall.mostPopular)
                .typographyV1(.caption5)
                .foregroundColor(Color.SemanticV1.textPrimary)
                .padding(.vertical, 2)
                .padding(.horizontal, 6)
                .background(
                    Image.Assets.defaultPink
                        .resizable()
                        .scaledToFill()
                )
                .clipShape(.rect(cornerRadius: 8))
                .environment(\.colorScheme, .dark)
            Spacer()
        }
    }

    @ViewBuilder
    private var bestValue: some View {
        HStack {
            Text(L10n.FeaturePaywall.bestValue)
                .typographyV1(.caption5)
                .foregroundColor(Color.SemanticV1.textPrimary)
                .padding(.vertical, 2)
                .padding(.horizontal, 6)
                .background(
                    Image.Assets.defaultOrange
                        .resizable()
                        .scaledToFill()
                )
                .clipShape(.rect(cornerRadius: 8))
                .environment(\.colorScheme, .dark)
            Spacer()
        }
    }
}

/// Returns (`x or ✓`, text) for each subscription
func getSubscriptionInfo(for key: String, isV5Launch: Bool = false) -> [(Bool, String)] {
    switch key {
    case "monthly.premier":
        return getSubscriptionInfo(for: "yearly.premier", isV5Launch: isV5Launch)

    case "monthly.pro":
        return [
            (true, isV5Launch ? L10n.FeaturePaywall.accessToV5Model : L10n.FeaturePaywall.accessToV45PlusModel),
            (true, L10n.FeaturePaywall.yearlyProStats1),
            (true, L10n.FeaturePaywall.yearlyProStats2),
            (true, L10n.FeaturePaywall.yearlyProStats3),
            (true, L10n.FeaturePaywall.yearlyProStats4),
            (true, L10n.FeaturePaywall.yearlyProStats5),
        ]

    case "yearly.premier":
        return [
            (true, isV5Launch ? L10n.FeaturePaywall.accessToV5Model : L10n.FeaturePaywall.accessToV45PlusModel),
            (true, L10n.FeaturePaywall.yearlyPremierStats1),
            (true, L10n.FeaturePaywall.yearlyProStats2),
            (true, L10n.FeaturePaywall.yearlyProStats3),
            (true, L10n.FeaturePaywall.yearlyProStats4),
            (true, L10n.FeaturePaywall.yearlyProStats5),
        ]

    case "yearly.pro":
        return [
            (true, isV5Launch ? L10n.FeaturePaywall.accessToV5Model : L10n.FeaturePaywall.accessToV45PlusModel),
            (true, L10n.FeaturePaywall.yearlyProStats1),
            (true, L10n.FeaturePaywall.yearlyProStats2),
            (true, L10n.FeaturePaywall.yearlyProStats3),
            (true, L10n.FeaturePaywall.yearlyProStats4),
            (true, L10n.FeaturePaywall.yearlyProStats5),
        ]

    case "yearly.basic_2025_05_01_a", "monthly.basic_2025_05_01_a":
        return [
            (true, L10n.FeaturePaywall.accessToV4Model),
            (true, L10n.FeaturePaywall.basicStats1),
            (false, L10n.FeaturePaywall.basicStats2),
            (true, L10n.FeaturePaywall.basicStats3),
            (true, L10n.FeaturePaywall.basicStats4),
            (true, L10n.FeaturePaywall.basicStats5),
        ]

    case "monthly.premier_2025_05_01_b", "monthly.premier_2025_05_01_a":
        return getSubscriptionInfo(for: "monthly.premier")

    case "yearly.premier_2025_05_01_b", "yearly.premier_2025_05_01_a":
        return getSubscriptionInfo(for: "yearly.premier")

    case "yearly.pro_2025_05_01_b", "yearly.pro_2025_05_01_a", "monthly.pro_2025_05_01_b", "monthly.pro_2025_05_01_a":
        return [
            (true, isV5Launch ? L10n.FeaturePaywall.accessToV5Model : L10n.FeaturePaywall.accessToV45PlusModel),
            (true, L10n.FeaturePaywall.yearlyPro20250501Stats1),
            (true, L10n.FeaturePaywall.yearlyProStats2),
            (true, L10n.FeaturePaywall.yearlyProStats3),
            (true, L10n.FeaturePaywall.yearlyProStats4),
            (true, L10n.FeaturePaywall.yearlyProStats5),
        ]

    case "free":
        return [
            (true, L10n.FeaturePaywall.accessToV35Model),
            (true, L10n.FeaturePaywall.freePlanStats1),
            (false, L10n.FeaturePaywall.freePlanStats2),
            (true, L10n.FeaturePaywall.freePlanStats3),
            (true, L10n.FeaturePaywall.freePlanStats4),
            (false, L10n.FeaturePaywall.freePlanStats5),
        ]

    default:
        return []
    }
}

private extension TypographyV1 {
    static let strikethroughPrice: TypographyV1 = .init(
        name: "Strikethrough Price",
        size: 16,
        style: .title,
        weight: .editorialNewLight,
        lineHeight: 32
    )
}
