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 bool isAvailable;
  final String? email;
  final AgentType? agentType;
  final AgentUser? user;
  final List<AgentFieldValue> fieldValues;
  final String? createdAt;
  final List<String> legacySpecializations;
  final List<String> languages;
  final List<String> serviceAreas;

  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.isAvailable = false,
    this.email,
    this.agentType,
    this.user,
    this.fieldValues = const [],
    this.createdAt,
    this.legacySpecializations = const [],
    this.languages = const [],
    this.serviceAreas = const [],
  });

  String get fullName => '$firstName $lastName'.trim();

  /// Format "Member Since March 2024" from createdAt date string.
  String get memberSinceText {
    if (createdAt == null || createdAt!.isEmpty) return 'Member Since 2024';
    try {
      final date = DateTime.parse(createdAt!);
      const months = [
        'January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December',
      ];
      return 'Member Since ${months[date.month - 1]} ${date.year}';
    } catch (_) {
      return 'Member Since 2024';
    }
  }

  /// Get avatar URL — check agent avatar first, then user avatar
  String? get avatarUrl => avatar ?? user?.avatar;

  /// Get description — check fieldValues 'description' first, then bio (matches web)
  String get description {
    for (final fv in fieldValues) {
      if (fv.fieldSlug == 'description' && fv.textValue != null && fv.textValue!.isNotEmpty) {
        return fv.textValue!;
      }
    }
    return bio ?? '';
  }

  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(', ');

    if (country != null && country!.isNotEmpty) return country!;
    if (serviceAreas.isNotEmpty) return serviceAreas.first;

    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<String> get specializations {
    final tags = <String>[];
    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);
      }
    }

    // Add from legacy specializations array
    for (final spec in legacySpecializations) {
      if (spec.isNotEmpty && !tags.contains(spec)) tags.add(spec);
    }

    // Add from languages array
    for (final lang in languages) {
      if (lang.isNotEmpty && !tags.contains(lang)) tags.add(lang);
    }

    return tags;
  }

  AgentProfile copyWith({bool? isAvailable}) {
    return AgentProfile(
      id: id,
      userId: userId,
      firstName: firstName,
      lastName: lastName,
      headline: headline,
      bio: bio,
      avatar: avatar,
      companyName: companyName,
      phone: phone,
      website: website,
      city: city,
      state: state,
      country: country,
      averageRating: averageRating,
      totalReviews: totalReviews,
      isVerified: isVerified,
      isFeatured: isFeatured,
      isActive: isActive,
      isAvailable: isAvailable ?? this.isAvailable,
      email: email,
      agentType: agentType,
      user: user,
      fieldValues: fieldValues,
      createdAt: createdAt,
      legacySpecializations: legacySpecializations,
      languages: languages,
      serviceAreas: serviceAreas,
    );
  }

  factory AgentProfile.fromJson(Map<String, dynamic> 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,
      isAvailable: json['isAvailable'] as bool? ?? false,
      email: json['email'] as String?,
      agentType: json['agentType'] != null
          ? AgentType.fromJson(json['agentType'] as Map<String, dynamic>)
          : null,
      user: json['user'] != null
          ? AgentUser.fromJson(json['user'] as Map<String, dynamic>)
          : null,
      fieldValues: (json['fieldValues'] as List<dynamic>?)
              ?.map((e) => AgentFieldValue.fromJson(e as Map<String, dynamic>))
              .toList() ??
          const [],
      createdAt: json['createdAt'] as String?,
      legacySpecializations: (json['specializations'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          const [],
      languages: (json['languages'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          const [],
      serviceAreas: (json['serviceAreas'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .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<String, dynamic> 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? sectionSlug;
  final String? sectionName;
  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.sectionSlug,
    this.sectionName,
    this.textValue,
    this.numberValue,
    this.booleanValue,
    this.jsonValue,
    this.dateValue,
  });

  /// Parse from the /agents/{id}/field-values endpoint format
  /// which has { fieldSlug, fieldName, fieldType, sectionSlug, value }
  factory AgentFieldValue.fromFieldValueResponse(Map<String, dynamic> json) {
    final value = json['value'];
    String? textValue;
    num? numberValue;
    bool? booleanValue;
    dynamic jsonValue;

    if (value is String) {
      textValue = value;
    } else if (value is num) {
      numberValue = value;
    } else if (value is bool) {
      booleanValue = value;
    } else if (value is List || value is Map) {
      jsonValue = value;
    }

    return AgentFieldValue(
      id: '',
      fieldSlug: json['fieldSlug'] as String? ?? '',
      fieldName: json['fieldName'] as String? ?? '',
      fieldType: json['fieldType'] as String? ?? '',
      sectionSlug: json['sectionSlug'] as String?,
      sectionName: json['sectionName'] as String?,
      textValue: textValue,
      numberValue: numberValue,
      booleanValue: booleanValue,
      jsonValue: jsonValue,
    );
  }

  factory AgentFieldValue.fromJson(Map<String, dynamic> json) {
    // API returns field info nested: { field: { slug, name, fieldType } }
    // Fallback to top-level fieldSlug/fieldName/fieldType for compatibility
    final field = json['field'] as Map<String, dynamic>?;
    return AgentFieldValue(
      id: json['id'] as String? ?? '',
      fieldSlug: field?['slug'] as String? ?? json['fieldSlug'] as String? ?? '',
      fieldName: field?['name'] as String? ?? json['fieldName'] as String? ?? '',
      fieldType: field?['fieldType'] as String? ?? 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?,
    );
  }
}
