import 'package:flutter/foundation.dart'; /// Immutable application-level user identity representation. /// Keeps Firebase types out of the presentation and telemetry layers. @immutable class AuthUser { final String uid; final String? email; final String? displayName; final String? photoUrl; final bool isAnonymous; final bool emailVerified; final String? providerId; final DateTime? createdAt; final DateTime? lastSignInTime; const AuthUser({ required this.uid, this.email, this.displayName, this.photoUrl, this.isAnonymous = false, this.emailVerified = false, this.providerId, this.createdAt, this.lastSignInTime, }); /// True if the user has an authenticated email or external identity bool get hasIdentifiedAccount => !isAnonymous && (email != null || displayName != null); /// Formatted display name fallback String get displayLabel { if (displayName != null && displayName!.isNotEmpty) return displayName!; if (email != null && email!.isNotEmpty) return email!; if (isAnonymous) return 'Anonymous Rider'; return 'Rider ($uid)'; } Map toJson() => { 'uid': uid, 'email': email, 'displayName': displayName, 'photoUrl': photoUrl, 'isAnonymous': isAnonymous, 'emailVerified': emailVerified, 'providerId': providerId, 'createdAt': createdAt?.toIso8601String(), 'lastSignInTime': lastSignInTime?.toIso8601String(), }; factory AuthUser.fromJson(Map json) => AuthUser( uid: json['uid'] as String? ?? '', email: json['email'] as String?, displayName: json['displayName'] as String?, photoUrl: json['photoUrl'] as String?, isAnonymous: json['isAnonymous'] as bool? ?? false, emailVerified: json['emailVerified'] as bool? ?? false, providerId: json['providerId'] as String?, createdAt: json['createdAt'] != null ? DateTime.tryParse(json['createdAt'] as String) : null, lastSignInTime: json['lastSignInTime'] != null ? DateTime.tryParse(json['lastSignInTime'] as String) : null, ); AuthUser copyWith({ String? uid, String? email, String? displayName, String? photoUrl, bool? isAnonymous, bool? emailVerified, String? providerId, DateTime? createdAt, DateTime? lastSignInTime, }) { return AuthUser( uid: uid ?? this.uid, email: email ?? this.email, displayName: displayName ?? this.displayName, photoUrl: photoUrl ?? this.photoUrl, isAnonymous: isAnonymous ?? this.isAnonymous, emailVerified: emailVerified ?? this.emailVerified, providerId: providerId ?? this.providerId, createdAt: createdAt ?? this.createdAt, lastSignInTime: lastSignInTime ?? this.lastSignInTime, ); } @override bool operator ==(Object other) => identical(this, other) || other is AuthUser && runtimeType == other.runtimeType && uid == other.uid && email == other.email && displayName == other.displayName && isAnonymous == other.isAnonymous && emailVerified == other.emailVerified && providerId == other.providerId; @override int get hashCode => uid.hashCode ^ email.hashCode ^ displayName.hashCode ^ isAnonymous.hashCode ^ emailVerified.hashCode ^ providerId.hashCode; @override String toString() => 'AuthUser(uid: $uid, email: $email, name: $displayName, anon: $isAnonymous, provider: $providerId)'; }