/// 구독 플랜 타입 enum SubscriptionPlanType { free, // 무료 플랜 basic, // 기본 유료 플랜 premium, // 프리미엄 플랜 enterprise // 기업용 플랜 } /// 구독 상태 enum SubscriptionStatus { active, // 활성화 상태 canceled, // 취소됨 (아직 만료 안됨) expired, // 만료됨 pending, // 결제 대기 중 failed // 결제 실패 } /// 구독 모델 class Subscription { final String id; final String userId; final String? clubId; final SubscriptionPlanType planType; final SubscriptionStatus status; final DateTime startDate; final DateTime endDate; final double price; final String currency; final bool autoRenew; final Map? features; final String? paymentMethod; final String? transactionId; final DateTime createdAt; final DateTime updatedAt; Subscription({ required this.id, required this.userId, this.clubId, required this.planType, required this.status, required this.startDate, required this.endDate, required this.price, required this.currency, required this.autoRenew, this.features, this.paymentMethod, this.transactionId, required this.createdAt, required this.updatedAt, }); /// JSON에서 구독 객체 생성 factory Subscription.fromJson(Map json) { return Subscription( id: json['id'], userId: json['userId'], clubId: json['clubId'], planType: SubscriptionPlanType.values.firstWhere( (e) => e.toString().split('.').last == json['planType'], orElse: () => SubscriptionPlanType.free, ), status: SubscriptionStatus.values.firstWhere( (e) => e.toString().split('.').last == json['status'], orElse: () => SubscriptionStatus.expired, ), startDate: DateTime.parse(json['startDate']), endDate: DateTime.parse(json['endDate']), price: json['price'].toDouble(), currency: json['currency'], autoRenew: json['autoRenew'] ?? false, features: json['features'], paymentMethod: json['paymentMethod'], transactionId: json['transactionId'], createdAt: DateTime.parse(json['createdAt']), updatedAt: DateTime.parse(json['updatedAt']), ); } /// 구독 객체를 JSON으로 변환 Map toJson() { return { 'id': id, 'userId': userId, 'clubId': clubId, 'planType': planType.toString().split('.').last, 'status': status.toString().split('.').last, 'startDate': startDate.toIso8601String(), 'endDate': endDate.toIso8601String(), 'price': price, 'currency': currency, 'autoRenew': autoRenew, 'features': features, 'paymentMethod': paymentMethod, 'transactionId': transactionId, 'createdAt': createdAt.toIso8601String(), 'updatedAt': updatedAt.toIso8601String(), }; } /// 구독이 활성 상태인지 확인 bool get isActive => status == SubscriptionStatus.active; /// 구독이 만료되었는지 확인 bool get isExpired => status == SubscriptionStatus.expired || DateTime.now().isAfter(endDate); /// 구독 남은 일수 계산 int get daysLeft { if (isExpired) return 0; return endDate.difference(DateTime.now()).inDays; } /// 구독 플랜 이름 (한글) String get planName { switch (planType) { case SubscriptionPlanType.free: return '무료'; case SubscriptionPlanType.basic: return '기본'; case SubscriptionPlanType.premium: return '프리미엄'; case SubscriptionPlanType.enterprise: return '기업용'; } } } /// 구독 플랜 정보 모델 class SubscriptionPlan { final SubscriptionPlanType type; final String name; final String description; final double monthlyPrice; final double yearlyPrice; final String currency; final List features; final int maxMembers; final int maxEvents; final bool hasAdvancedStats; final bool hasCustomization; final bool hasPriority; SubscriptionPlan({ required this.type, required this.name, required this.description, required this.monthlyPrice, required this.yearlyPrice, required this.currency, required this.features, required this.maxMembers, required this.maxEvents, required this.hasAdvancedStats, required this.hasCustomization, required this.hasPriority, }); /// JSON에서 구독 플랜 객체 생성 factory SubscriptionPlan.fromJson(Map json) { return SubscriptionPlan( type: SubscriptionPlanType.values.firstWhere( (e) => e.toString().split('.').last == json['type'], orElse: () => SubscriptionPlanType.free, ), name: json['name'], description: json['description'], monthlyPrice: json['monthlyPrice'].toDouble(), yearlyPrice: json['yearlyPrice'].toDouble(), currency: json['currency'], features: List.from(json['features']), maxMembers: json['maxMembers'], maxEvents: json['maxEvents'], hasAdvancedStats: json['hasAdvancedStats'] ?? false, hasCustomization: json['hasCustomization'] ?? false, hasPriority: json['hasPriority'] ?? false, ); } /// 구독 플랜 객체를 JSON으로 변환 Map toJson() { return { 'type': type.toString().split('.').last, 'name': name, 'description': description, 'monthlyPrice': monthlyPrice, 'yearlyPrice': yearlyPrice, 'currency': currency, 'features': features, 'maxMembers': maxMembers, 'maxEvents': maxEvents, 'hasAdvancedStats': hasAdvancedStats, 'hasCustomization': hasCustomization, 'hasPriority': hasPriority, }; } /// 기본 구독 플랜 목록 반환 static List getDefaultPlans() { return [ SubscriptionPlan( type: SubscriptionPlanType.free, name: '무료', description: '소규모 클럽을 위한 기본 기능', monthlyPrice: 0, yearlyPrice: 0, currency: 'KRW', features: [ '최대 10명 회원 관리', '기본 점수 기록', '간단한 통계', ], maxMembers: 10, maxEvents: 5, hasAdvancedStats: false, hasCustomization: false, hasPriority: false, ), SubscriptionPlan( type: SubscriptionPlanType.basic, name: '기본', description: '중소규모 클럽을 위한 확장 기능', monthlyPrice: 9900, yearlyPrice: 99000, currency: 'KRW', features: [ '최대 30명 회원 관리', '상세 점수 분석', '이벤트 관리', '회원 통계', ], maxMembers: 30, maxEvents: 20, hasAdvancedStats: true, hasCustomization: false, hasPriority: false, ), SubscriptionPlan( type: SubscriptionPlanType.premium, name: '프리미엄', description: '대규모 클럽을 위한 고급 기능', monthlyPrice: 19900, yearlyPrice: 199000, currency: 'KRW', features: [ '무제한 회원 관리', '고급 통계 및 분석', '무제한 이벤트', '맞춤형 보고서', '우선 지원', ], maxMembers: 100, maxEvents: 100, hasAdvancedStats: true, hasCustomization: true, hasPriority: true, ), SubscriptionPlan( type: SubscriptionPlanType.enterprise, name: '기업용', description: '프로 클럽 및 단체를 위한 맞춤형 솔루션', monthlyPrice: 49900, yearlyPrice: 499000, currency: 'KRW', features: [ '무제한 회원 및 이벤트', '전문가 수준 분석', '맞춤형 기능', '전담 지원', 'API 액세스', ], maxMembers: 1000, maxEvents: 1000, hasAdvancedStats: true, hasCustomization: true, hasPriority: true, ), ]; } }