import 'package:afterwork/domain/entities/event.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Event Entity', () {
    final tStartDate = DateTime(2026, 1, 15, 19, 0);

    test('should create an Event with required fields', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'After-work Tech',
        description: 'Soirée networking',
        startDate: tStartDate,
        location: 'Paris, France',
        category: 'Networking',
        creatorEmail: 'john@example.com',
        creatorFirstName: 'John',
        creatorLastName: 'Doe',
        creatorProfileImageUrl: 'https://example.com/profile.jpg',
      );

      // Assert
      expect(event.id, '1');
      expect(event.title, 'After-work Tech');
      expect(event.description, 'Soirée networking');
      expect(event.startDate, tStartDate);
      expect(event.location, 'Paris, France');
      expect(event.category, 'Networking');
      expect(event.creatorEmail, 'john@example.com');
      expect(event.creatorFirstName, 'John');
      expect(event.creatorLastName, 'Doe');
      expect(event.status, EventStatus.open); // Default
      expect(event.participantIds, isEmpty);
      expect(event.reactionsCount, 0);
      expect(event.commentsCount, 0);
      expect(event.sharesCount, 0);
    });

    test('should create an Event with optional fields', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'After-work Tech',
        description: 'Soirée networking',
        startDate: tStartDate,
        location: 'Paris, France',
        category: 'Networking',
        link: 'https://event.com',
        imageUrl: 'https://event.com/image.jpg',
        creatorEmail: 'john@example.com',
        creatorFirstName: 'John',
        creatorLastName: 'Doe',
        creatorProfileImageUrl: 'https://example.com/profile.jpg',
        participantIds: const ['user1', 'user2'],
        status: EventStatus.closed,
        reactionsCount: 10,
        commentsCount: 5,
        sharesCount: 3,
      );

      // Assert
      expect(event.link, 'https://event.com');
      expect(event.imageUrl, 'https://event.com/image.jpg');
      expect(event.participantIds, ['user1', 'user2']);
      expect(event.status, EventStatus.closed);
      expect(event.reactionsCount, 10);
      expect(event.commentsCount, 5);
      expect(event.sharesCount, 3);
    });

    test('should return correct creator full name', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'Test Event',
        description: 'Test',
        startDate: tStartDate,
        location: 'Test Location',
        category: 'Test',
        creatorEmail: 'john@example.com',
        creatorFirstName: 'John',
        creatorLastName: 'Doe',
        creatorProfileImageUrl: 'test.jpg',
      );

      // Assert
      expect(event.creatorFullName, 'John Doe');
    });

    test('should return correct participants count', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'Test Event',
        description: 'Test',
        startDate: tStartDate,
        location: 'Test Location',
        category: 'Test',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
        participantIds: const ['user1', 'user2', 'user3'],
      );

      // Assert
      expect(event.participantsCount, 3);
    });

    test('isOpen should return true when status is open', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'Test Event',
        description: 'Test',
        startDate: tStartDate,
        location: 'Test Location',
        category: 'Test',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
        status: EventStatus.open,
      );

      // Assert
      expect(event.isOpen, isTrue);
      expect(event.isClosed, isFalse);
      expect(event.isCancelled, isFalse);
    });

    test('isClosed should return true when status is closed', () {
      // Arrange & Act
      final event = Event(
        id: '1',
        title: 'Test Event',
        description: 'Test',
        startDate: tStartDate,
        location: 'Test Location',
        category: 'Test',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
        status: EventStatus.closed,
      );

      // Assert
      expect(event.isClosed, isTrue);
      expect(event.isOpen, isFalse);
      expect(event.isCancelled, isFalse);
    });

    test('copyWith should create a new instance with updated fields', () {
      // Arrange
      final original = Event(
        id: '1',
        title: 'Original Title',
        description: 'Original Description',
        startDate: tStartDate,
        location: 'Original Location',
        category: 'Original Category',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
      );

      // Act
      final updated = original.copyWith(
        title: 'Updated Title',
        status: EventStatus.closed,
      );

      // Assert
      expect(updated.id, original.id); // Unchanged
      expect(updated.title, 'Updated Title'); // Changed
      expect(updated.description, original.description); // Unchanged
      expect(updated.status, EventStatus.closed); // Changed
    });

    test('should support value equality using Equatable', () {
      // Arrange
      final event1 = Event(
        id: '1',
        title: 'Event',
        description: 'Description',
        startDate: tStartDate,
        location: 'Location',
        category: 'Category',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
      );

      final event2 = Event(
        id: '1',
        title: 'Event',
        description: 'Description',
        startDate: tStartDate,
        location: 'Location',
        category: 'Category',
        creatorEmail: 'test@example.com',
        creatorFirstName: 'Test',
        creatorLastName: 'User',
        creatorProfileImageUrl: 'test.jpg',
      );

      // Assert
      expect(event1, equals(event2));
    });
  });

  group('EventStatus', () {
    test('fromString should convert "ouvert" to open', () {
      expect(EventStatus.fromString('ouvert'), EventStatus.open);
      expect(EventStatus.fromString('open'), EventStatus.open);
    });

    test('fromString should convert "fermé" to closed', () {
      expect(EventStatus.fromString('fermé'), EventStatus.closed);
      expect(EventStatus.fromString('ferme'), EventStatus.closed);
      expect(EventStatus.fromString('closed'), EventStatus.closed);
    });

    test('fromString should convert "annulé" to cancelled', () {
      expect(EventStatus.fromString('annulé'), EventStatus.cancelled);
      expect(EventStatus.fromString('annule'), EventStatus.cancelled);
      expect(EventStatus.fromString('cancelled'), EventStatus.cancelled);
    });

    test('fromString should convert "terminé" to completed', () {
      expect(EventStatus.fromString('terminé'), EventStatus.completed);
      expect(EventStatus.fromString('termine'), EventStatus.completed);
      expect(EventStatus.fromString('completed'), EventStatus.completed);
    });

    test('fromString should return open for unknown status', () {
      expect(EventStatus.fromString('unknown'), EventStatus.open);
      expect(EventStatus.fromString(''), EventStatus.open);
    });

    test('toApiString should convert status to French API strings', () {
      expect(EventStatus.open.toApiString(), 'ouvert');
      expect(EventStatus.closed.toApiString(), 'fermé');
      expect(EventStatus.cancelled.toApiString(), 'annulé');
      expect(EventStatus.completed.toApiString(), 'terminé');
    });
  });
}

