import Foundation
import GenAPI
import SunoModelClient

public extension SubscriptionInfoResponse {
    // Each song creation generate two songs and costs 10 credits
    static let generateSongCost = 10

    var sunoModelUserAccess: SunoModelUserAccess {
        return .init(
            remasterAccess: remasterAccessCategory,
            v4Access: v4AccessCategory
        )
    }

    var songsLeft: Int {
        return totalCreditsLeft / (SubscriptionInfoResponse.generateSongCost / 2)
    }
}

private extension SubscriptionInfoResponse {
    var v4AccessCategory: UserV4AccessCategory {
        if let plan, plan.usagePlanFeatures.contains(FeatureSchema(name: FeatureName.v4)) {
            return .paidUser
        } else {
            let freeV4LifetimeGenerationsRemaining = freeMobileV4GensRemaining ?? .zero
            if freeV4LifetimeGenerationsRemaining > .zero {
                return .freeUserWithFreeLifetimeGenerationsLeft(freeV4LifetimeGenerationsRemaining)
            } else {
                return .freeUserWithoutFreeLifetimeGenerationsLeft
            }
        }
    }

    var remasterAccessCategory: UserRemasterAccessCategory {
        if let plan, plan.usagePlanFeatures.contains(FeatureSchema(name: FeatureName.v4)) {
            return .paidUser
        } else {
            let freeLifetimeRemasterGenerationsRemaining = freeMobileRemastersRemaining ?? .zero
            if freeLifetimeRemasterGenerationsRemaining > .zero {
                return .freeUserWithFreeLifetimeGenerationsLeft(freeLifetimeRemasterGenerationsRemaining)
            } else {
                return .freeUserWithoutFreeLifetimeGenerationsLeft
            }
        }
    }
}

// TEMP, we should think through our model update pipe and figure out a good place for this to live.
public extension SunoModelClient {
    /// Helper to configure SunoModelClient
    func configureWithSubscriptionInfoResponse(userId: String, response: SubscriptionInfoResponse) async {
        await configure(
            response.models.compactMap { SunoModelMetaData($0) },
            response.sunoModelUserAccess,
            userId,
            response.remasterModelTypes?.map { RemasterModelMetaData($0) }
        )
    }
}

extension SubscriptionInfoResponse {
    static func mock(
        accessibleFeatures: [FeatureSchema]
    ) -> Self {
        .init(
            accessibleFeatures: accessibleFeatures,
            audioUploadLimits: .init(max: 0, min: 0),
            creditPacks: [],
            credits: 0,
            hasBeenStudentSubscriberBefore: false,
            hasBeenSubscriberBefore: false,
            hasValidSchoolEmail: false,
            isActive: true,
            isPastDue: false,
            models: [],
            monthlyLimit: 0,
            monthlyUsage: 0,
            plans: [],
            subscriptionType: false,
            totalCreditsLeft: 0
        )
    }
}
