import 'package:equatable/equatable.dart';

/// Entité de domaine représentant un établissement.
///
/// Un établissement est un lieu physique (bar, restaurant, club, etc.)
/// où peuvent se dérouler des événements Afterwork.
class Establishment extends Equatable {
  const Establishment({
    required this.id,
    required this.name,
    required this.type,
    required this.address,
    required this.city,
    required this.postalCode,
    this.description,
    this.phoneNumber,
    this.email,
    this.website,
    this.imageUrl,
    this.rating,
    this.priceRange,
    this.capacity,
    this.amenities = const [],
    this.openingHours,
    this.latitude,
    this.longitude,
  });

  final String id;
  final String name;
  final EstablishmentType type;
  final String address;
  final String city;
  final String postalCode;
  final String? description;
  final String? phoneNumber;
  final String? email;
  final String? website;
  final String? imageUrl;
  final double? rating; // Note moyenne sur 5
  final PriceRange? priceRange;
  final int? capacity; // Capacité maximale
  final List<String> amenities; // WiFi, Terrasse, Parking, etc.
  final String? openingHours;
  final double? latitude;
  final double? longitude;

  /// Adresse complète formatée
  String get fullAddress => '$address, $postalCode $city';

  /// Indique si l'établissement a une localisation
  bool get hasLocation => latitude != null && longitude != null;

  @override
  List<Object?> get props => [
        id,
        name,
        type,
        address,
        city,
        postalCode,
        description,
        phoneNumber,
        email,
        website,
        imageUrl,
        rating,
        priceRange,
        capacity,
        amenities,
        openingHours,
        latitude,
        longitude,
      ];

  /// Crée une copie de cet établissement avec des valeurs modifiées.
  Establishment copyWith({
    String? id,
    String? name,
    EstablishmentType? type,
    String? address,
    String? city,
    String? postalCode,
    String? description,
    String? phoneNumber,
    String? email,
    String? website,
    String? imageUrl,
    double? rating,
    PriceRange? priceRange,
    int? capacity,
    List<String>? amenities,
    String? openingHours,
    double? latitude,
    double? longitude,
  }) {
    return Establishment(
      id: id ?? this.id,
      name: name ?? this.name,
      type: type ?? this.type,
      address: address ?? this.address,
      city: city ?? this.city,
      postalCode: postalCode ?? this.postalCode,
      description: description ?? this.description,
      phoneNumber: phoneNumber ?? this.phoneNumber,
      email: email ?? this.email,
      website: website ?? this.website,
      imageUrl: imageUrl ?? this.imageUrl,
      rating: rating ?? this.rating,
      priceRange: priceRange ?? this.priceRange,
      capacity: capacity ?? this.capacity,
      amenities: amenities ?? this.amenities,
      openingHours: openingHours ?? this.openingHours,
      latitude: latitude ?? this.latitude,
      longitude: longitude ?? this.longitude,
    );
  }
}

/// Type d'établissement.
enum EstablishmentType {
  bar,
  restaurant,
  club,
  cafe,
  lounge,
  pub,
  brewery,
  winery,
  other,
}

/// Fourchette de prix.
enum PriceRange {
  cheap, // €
  moderate, // €€
  expensive, // €€€
  luxury, // €€€€
}

/// Extensions pour faciliter l'utilisation.
extension EstablishmentTypeExtension on EstablishmentType {
  String get displayName {
    switch (this) {
      case EstablishmentType.bar:
        return 'Bar';
      case EstablishmentType.restaurant:
        return 'Restaurant';
      case EstablishmentType.club:
        return 'Club';
      case EstablishmentType.cafe:
        return 'Café';
      case EstablishmentType.lounge:
        return 'Lounge';
      case EstablishmentType.pub:
        return 'Pub';
      case EstablishmentType.brewery:
        return 'Brasserie';
      case EstablishmentType.winery:
        return 'Cave à vin';
      case EstablishmentType.other:
        return 'Autre';
    }
  }

  String get icon {
    switch (this) {
      case EstablishmentType.bar:
        return '🍸';
      case EstablishmentType.restaurant:
        return '🍽️';
      case EstablishmentType.club:
        return '💃';
      case EstablishmentType.cafe:
        return '☕';
      case EstablishmentType.lounge:
        return '🛋️';
      case EstablishmentType.pub:
        return '🍺';
      case EstablishmentType.brewery:
        return '🍻';
      case EstablishmentType.winery:
        return '🍷';
      case EstablishmentType.other:
        return '📍';
    }
  }
}

extension PriceRangeExtension on PriceRange {
  String get symbol {
    switch (this) {
      case PriceRange.cheap:
        return '€';
      case PriceRange.moderate:
        return '€€';
      case PriceRange.expensive:
        return '€€€';
      case PriceRange.luxury:
        return '€€€€';
    }
  }

  String get displayName {
    switch (this) {
      case PriceRange.cheap:
        return 'Économique';
      case PriceRange.moderate:
        return 'Modéré';
      case PriceRange.expensive:
        return 'Cher';
      case PriceRange.luxury:
        return 'Luxe';
    }
  }
}
