import 'package:equatable/equatable.dart';
import 'package:flux/features/master_data/providers/models/provider_model.dart';
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';

class StoreModel extends Equatable {
  final String? id;
  final String name;
  final String companyId;
  final bool isActive;
  final bool isPaid;
  final DateTime? paymentExpiration;
  final String address;
  final String zipCode;
  final String city;
  final String province;
  final List<ProviderModel> associatedProviders; // Provider associati
  final List<StaffMemberModel>
  associatedStaffMembers; // Membri dello staff associati
  final String? defaultProviderId; // ID del provider di default (opzionale)

  const StoreModel({
    this.id,
    required this.name,
    required this.companyId,
    this.isActive = true,
    this.isPaid = false,
    this.paymentExpiration,
    required this.address,
    required this.zipCode,
    required this.city,
    required this.province,
    this.associatedProviders = const [],
    this.associatedStaffMembers = const [],
    this.defaultProviderId,
  });

  // Fondamentale per Equatable: definisce quali proprietà determinano l'uguaglianza
  @override
  List<Object?> get props => [
    id,
    name,
    companyId,
    isActive,
    isPaid,
    paymentExpiration,
    address,
    zipCode,
    city,
    province,
    associatedProviders,
    associatedStaffMembers,
    defaultProviderId,
  ];

  // Il mitico copyWith per creare nuove istanze modificando solo ciò che serve
  StoreModel copyWith({
    String? id,
    String? name,
    String? companyId,
    bool? isActive,
    bool? isPaid,
    DateTime? paymentExpiration,
    String? address,
    String? zipCode,
    String? city,
    String? province,
    List<ProviderModel>? associatedProviders,
    List<StaffMemberModel>? associatedStaffMembers,
    String? Function()? defaultProviderId,
  }) {
    return StoreModel(
      id: id ?? this.id,
      name: name ?? this.name,
      companyId: companyId ?? this.companyId,
      isActive: isActive ?? this.isActive,
      isPaid: isPaid ?? this.isPaid,
      paymentExpiration: paymentExpiration ?? this.paymentExpiration,
      address: address ?? this.address,
      zipCode: zipCode ?? this.zipCode,
      city: city ?? this.city,
      province: province ?? this.province,
      associatedProviders: associatedProviders ?? this.associatedProviders,
      associatedStaffMembers:
          associatedStaffMembers ?? this.associatedStaffMembers,
      defaultProviderId: defaultProviderId != null
          ? defaultProviderId()
          : this.defaultProviderId,
    );
  }

  factory StoreModel.empty() {
    return const StoreModel(
      name: '',
      companyId: '',
      address: '',
      zipCode: '',
      city: '',
      province: '',
    );
  }

  factory StoreModel.fromMap(Map<String, dynamic> map) {
    final providersPivotList = map['associated_providers'] as List?;
    List<ProviderModel> providers = [];
    if (providersPivotList != null) {
      providers = providersPivotList
          .where((item) => item['provider'] != null) // Sicurezza
          .map(
            (item) =>
                ProviderModel.fromMap(item['provider'] as Map<String, dynamic>),
          )
          .toList();
    }
    final staffPivotList = map['associated_staff'] as List?;
    List<StaffMemberModel> staffMembers = [];
    if (staffPivotList != null) {
      staffMembers = staffPivotList
          .where((item) => item['staff_member'] != null) // Sicurezza
          .map(
            (item) => StaffMemberModel.fromMap(
              item['staff_member'] as Map<String, dynamic>,
            ),
          )
          .toList();
    }
    return StoreModel(
      id: map['id'] as String,
      name: map['name'],
      companyId: map['company_id'] as String,
      isActive: map['is_active'] ?? true,
      isPaid: map['is_paid'] ?? false,
      paymentExpiration: map['payment_expiration'] != null
          ? DateTime.parse(map['payment_expiration'])
          : null,
      address: map['address'],
      zipCode: map['zip_code'],
      city: map['city'],
      province: map['province'],
      associatedProviders: providers,
      associatedStaffMembers: staffMembers,
      defaultProviderId: map['default_provider_id'] as String?,
    );
  }

  Map<String, dynamic> toMap() {
    return {
      if (id != null) 'id': id,
      'name': name,
      'company_id': companyId,
      'is_active': isActive,
      'is_paid': isPaid,
      if (paymentExpiration != null)
        'payment_expiration': paymentExpiration!.toIso8601String(),
      'address': address,
      'zip_code': zipCode,
      'city': city,
      'province': province,
      'default_provider_id': defaultProviderId,
    };
  }
}
