import 'tenant.dart'; enum PlatformRole { superAdmin, support, financeOps, operations, readOnly, ; String get value => switch (this) { PlatformRole.superAdmin => 'super_admin', PlatformRole.support => 'support', PlatformRole.financeOps => 'finance_ops', PlatformRole.operations => 'operations', PlatformRole.readOnly => 'read_only', }; String get label => switch (this) { PlatformRole.superAdmin => 'Super Admin', PlatformRole.support => 'Destek', PlatformRole.financeOps => 'Finans Operasyon', PlatformRole.operations => 'Operasyon', PlatformRole.readOnly => 'Sadece Görüntüleme', }; static PlatformRole parse(String raw) => switch (raw) { 'super_admin' => PlatformRole.superAdmin, 'support' => PlatformRole.support, 'finance_ops' => PlatformRole.financeOps, 'operations' => PlatformRole.operations, 'read_only' => PlatformRole.readOnly, _ => PlatformRole.readOnly, }; } class PlatformMembership { const PlatformMembership({ required this.id, required this.userId, required this.role, this.status = 'active', }); final String id; final String userId; final PlatformRole role; final String status; bool get isActive => status == 'active'; bool get isSuperAdmin => role == PlatformRole.superAdmin && isActive; bool get canManageBilling => isActive && (role == PlatformRole.superAdmin || role == PlatformRole.financeOps); bool get canManageTenants => isActive && (role == PlatformRole.superAdmin || role == PlatformRole.operations || role == PlatformRole.support); factory PlatformMembership.fromJson(Map json) { return PlatformMembership( id: json['id'] as String, userId: json['user_id'] as String, role: PlatformRole.parse(json['role'] as String? ?? ''), status: (json['status'] as String?) ?? 'active', ); } } enum SubscriptionStatus { trialing, active, pastDue, cancelled, paused } extension SubscriptionStatusX on SubscriptionStatus { String get value => switch (this) { SubscriptionStatus.trialing => 'trialing', SubscriptionStatus.active => 'active', SubscriptionStatus.pastDue => 'past_due', SubscriptionStatus.cancelled => 'cancelled', SubscriptionStatus.paused => 'paused', }; static SubscriptionStatus parse(String raw) => switch (raw) { 'trialing' => SubscriptionStatus.trialing, 'active' => SubscriptionStatus.active, 'past_due' => SubscriptionStatus.pastDue, 'cancelled' => SubscriptionStatus.cancelled, 'paused' => SubscriptionStatus.paused, _ => SubscriptionStatus.trialing, }; } class TenantSubscription { const TenantSubscription({ required this.id, required this.tenantId, required this.plan, required this.status, this.billingProvider, this.providerCustomerId, this.providerSubscriptionId, this.periodStart, this.periodEnd, this.aiMonthlyCredits = 0, this.aiBonusCredits = 0, }); final String id; final String tenantId; final TenantPlan plan; final SubscriptionStatus status; final String? billingProvider; final String? providerCustomerId; final String? providerSubscriptionId; final DateTime? periodStart; final DateTime? periodEnd; final int aiMonthlyCredits; final int aiBonusCredits; int get totalAiCredits => aiMonthlyCredits + aiBonusCredits; factory TenantSubscription.fromJson(Map json) { return TenantSubscription( id: json['id'] as String, tenantId: json['tenant_id'] as String, plan: Tenant.parsePlanValue(json['plan'] as String?), status: SubscriptionStatusX.parse(json['status'] as String? ?? ''), billingProvider: json['billing_provider'] as String?, providerCustomerId: json['provider_customer_id'] as String?, providerSubscriptionId: json['provider_subscription_id'] as String?, periodStart: _parseDate(json['period_start']), periodEnd: _parseDate(json['period_end']), aiMonthlyCredits: (json['ai_monthly_credits'] as num?)?.toInt() ?? 0, aiBonusCredits: (json['ai_bonus_credits'] as num?)?.toInt() ?? 0, ); } } enum AiCreditEntryType { monthlyAllocation, bonusAllocation, usageDebit, manualAdjustment, refund, expire, ; String get value => switch (this) { AiCreditEntryType.monthlyAllocation => 'monthly_allocation', AiCreditEntryType.bonusAllocation => 'bonus_allocation', AiCreditEntryType.usageDebit => 'usage_debit', AiCreditEntryType.manualAdjustment => 'manual_adjustment', AiCreditEntryType.refund => 'refund', AiCreditEntryType.expire => 'expire', }; static AiCreditEntryType parse(String raw) => switch (raw) { 'monthly_allocation' => AiCreditEntryType.monthlyAllocation, 'bonus_allocation' => AiCreditEntryType.bonusAllocation, 'usage_debit' => AiCreditEntryType.usageDebit, 'manual_adjustment' => AiCreditEntryType.manualAdjustment, 'refund' => AiCreditEntryType.refund, 'expire' => AiCreditEntryType.expire, _ => AiCreditEntryType.manualAdjustment, }; } class AiCreditLedgerEntry { const AiCreditLedgerEntry({ required this.id, required this.tenantId, required this.entryType, required this.delta, required this.balanceAfter, this.referenceType, this.referenceId, this.note, this.createdByUserId, this.createdAt, }); final String id; final String tenantId; final AiCreditEntryType entryType; final int delta; final int balanceAfter; final String? referenceType; final String? referenceId; final String? note; final String? createdByUserId; final DateTime? createdAt; factory AiCreditLedgerEntry.fromJson(Map json) { return AiCreditLedgerEntry( id: json['id'] as String, tenantId: json['tenant_id'] as String, entryType: AiCreditEntryType.parse(json['entry_type'] as String? ?? ''), delta: (json['delta'] as num?)?.toInt() ?? 0, balanceAfter: (json['balance_after'] as num?)?.toInt() ?? 0, referenceType: json['reference_type'] as String?, referenceId: json['reference_id'] as String?, note: json['note'] as String?, createdByUserId: json['created_by_user_id'] as String?, createdAt: _parseDate(json['created']), ); } } class AiUsageLog { const AiUsageLog({ required this.id, required this.tenantId, required this.userId, required this.action, required this.creditCost, this.model, this.jobId, this.tokenInput, this.tokenOutput, this.latencyMs, this.createdAt, }); final String id; final String tenantId; final String userId; final String action; final int creditCost; final String? model; final String? jobId; final int? tokenInput; final int? tokenOutput; final int? latencyMs; final DateTime? createdAt; factory AiUsageLog.fromJson(Map json) { return AiUsageLog( id: json['id'] as String, tenantId: json['tenant_id'] as String, userId: json['user_id'] as String, action: json['action'] as String? ?? '', creditCost: (json['credit_cost'] as num?)?.toInt() ?? 0, model: json['model'] as String?, jobId: json['job_id'] as String?, tokenInput: (json['token_input'] as num?)?.toInt(), tokenOutput: (json['token_output'] as num?)?.toInt(), latencyMs: (json['latency_ms'] as num?)?.toInt(), createdAt: _parseDate(json['created']), ); } } class AdminAuditLog { const AdminAuditLog({ required this.id, required this.actorUserId, required this.actorRole, required this.actionType, this.targetCollection, this.targetRecordId, this.targetTenantId, this.summary, this.metadata, this.createdAt, }); final String id; final String actorUserId; final PlatformRole actorRole; final String actionType; final String? targetCollection; final String? targetRecordId; final String? targetTenantId; final String? summary; final Map? metadata; final DateTime? createdAt; factory AdminAuditLog.fromJson(Map json) { final metadata = json['metadata']; return AdminAuditLog( id: json['id'] as String, actorUserId: json['actor_user_id'] as String, actorRole: PlatformRole.parse(json['actor_role'] as String? ?? ''), actionType: json['action_type'] as String? ?? '', targetCollection: json['target_collection'] as String?, targetRecordId: json['target_record_id'] as String?, targetTenantId: json['target_tenant_id'] as String?, summary: json['summary'] as String?, metadata: metadata is Map ? metadata : null, createdAt: _parseDate(json['created']), ); } } DateTime? _parseDate(dynamic raw) { final value = raw as String?; if (value == null || value.isEmpty) return null; return DateTime.tryParse(value); }