import 'package:real_estate_mobile/features/agents/data/models/agent_type.dart'; class AgentProfile { final String id; final String? userId; final String firstName; final String lastName; final String? headline; final String? bio; final String? avatar; final String? companyName; final String? phone; final String? website; final String? city; final String? state; final String? country; final double? averageRating; final int totalReviews; final bool isVerified; final bool isFeatured; final bool isActive; final AgentType? agentType; final AgentUser? user; final List fieldValues; const AgentProfile({ required this.id, this.userId, required this.firstName, required this.lastName, this.headline, this.bio, this.avatar, this.companyName, this.phone, this.website, this.city, this.state, this.country, this.averageRating, this.totalReviews = 0, this.isVerified = false, this.isFeatured = false, this.isActive = true, this.agentType, this.user, this.fieldValues = const [], }); String get fullName => '$firstName $lastName'.trim(); /// Get avatar URL — check agent avatar first, then user avatar String? get avatarUrl => avatar ?? user?.avatar; String get location { // Direct fields first if (city != null && state != null) return '$city, $state'; if (city != null) return city!; if (state != null) return state!; // Fallback: extract from fieldValues (matches web getLocationString) String? fvCity; String? fvState; for (final fv in fieldValues) { final slug = fv.fieldSlug.toLowerCase(); if (slug == 'city' || slug == 'city_name') { fvCity = _extractFieldString(fv); } else if (slug == 'state' || slug == 'state_name') { fvState = _extractFieldString(fv); } } final parts = [fvCity, fvState].where((s) => s != null && s.isNotEmpty); if (parts.isNotEmpty) return parts.join(', '); return ''; } /// Extract a display string from a field value (handles jsonValue arrays). static String? _extractFieldString(AgentFieldValue fv) { if (fv.jsonValue is List && (fv.jsonValue as List).isNotEmpty) { final val = (fv.jsonValue as List).first; if (val is String && val.isNotEmpty) { return val .split('_') .map((w) => w.isNotEmpty ? '${w[0].toUpperCase()}${w.substring(1).toLowerCase()}' : '') .join(' '); } } if (fv.textValue != null && fv.textValue!.isNotEmpty) return fv.textValue; return null; } /// Get experience from field values String get experienceText { for (final fv in fieldValues) { if (fv.fieldSlug.contains('experience') || fv.fieldName.toLowerCase().contains('experience')) { if (fv.textValue != null) return fv.textValue!; if (fv.numberValue != null) { return '${fv.numberValue!.toInt()}+ years in real estate.'; } } } return ''; } /// Get specializations / expertise from field values. /// Matches web's getExpertiseTags slugs. List get specializations { final tags = []; const expertiseSlugs = [ 'about_me_expertise', 'expertise_areas', 'specializations', 'areas_of_expertise', 'expertise', 'specialization', 'property_type', 'loan_type', ]; for (final fv in fieldValues) { final slug = fv.fieldSlug.toLowerCase(); if (!expertiseSlugs.any((s) => slug.contains(s))) continue; if (fv.jsonValue is List) { for (final v in (fv.jsonValue as List)) { final s = v.toString().trim(); if (s.isEmpty) continue; final display = s .split('_') .map((w) => w.isNotEmpty ? '${w[0].toUpperCase()}${w.substring(1).toLowerCase()}' : '') .join(' '); if (!tags.contains(display)) tags.add(display); } } else if (fv.textValue != null && fv.textValue!.trim().isNotEmpty) { final display = fv.textValue!.trim(); if (!tags.contains(display)) tags.add(display); } } return tags; } factory AgentProfile.fromJson(Map json) { return AgentProfile( id: json['id'] as String, userId: json['userId'] as String?, firstName: json['firstName'] as String? ?? '', lastName: json['lastName'] as String? ?? '', headline: json['headline'] as String?, bio: json['bio'] as String?, avatar: json['avatar'] as String?, companyName: json['companyName'] as String?, phone: json['phone'] as String?, website: json['website'] as String?, city: json['city'] as String?, state: json['state'] as String?, country: json['country'] as String?, averageRating: (json['averageRating'] as num?)?.toDouble(), totalReviews: json['totalReviews'] as int? ?? 0, isVerified: json['isVerified'] as bool? ?? false, isFeatured: json['isFeatured'] as bool? ?? false, isActive: json['isActive'] as bool? ?? true, agentType: json['agentType'] != null ? AgentType.fromJson(json['agentType'] as Map) : null, user: json['user'] != null ? AgentUser.fromJson(json['user'] as Map) : null, fieldValues: (json['fieldValues'] as List?) ?.map((e) => AgentFieldValue.fromJson(e as Map)) .toList() ?? const [], ); } } class AgentUser { final String id; final String email; final String? avatar; const AgentUser({ required this.id, required this.email, this.avatar, }); factory AgentUser.fromJson(Map json) { return AgentUser( id: json['id'] as String, email: json['email'] as String? ?? '', avatar: json['avatar'] as String?, ); } } class AgentFieldValue { final String id; final String fieldSlug; final String fieldName; final String fieldType; final String? textValue; final num? numberValue; final bool? booleanValue; final dynamic jsonValue; final String? dateValue; const AgentFieldValue({ required this.id, required this.fieldSlug, required this.fieldName, required this.fieldType, this.textValue, this.numberValue, this.booleanValue, this.jsonValue, this.dateValue, }); factory AgentFieldValue.fromJson(Map json) { return AgentFieldValue( id: json['id'] as String? ?? '', fieldSlug: json['fieldSlug'] as String? ?? '', fieldName: json['fieldName'] as String? ?? '', fieldType: json['fieldType'] as String? ?? '', textValue: json['textValue'] as String?, numberValue: json['numberValue'] as num?, booleanValue: json['booleanValue'] as bool?, jsonValue: json['jsonValue'], dateValue: json['dateValue'] as String?, ); } }