import 'package:flutter_test/flutter_test.dart';
import 'package:agenda_tasks/features/tasks/domain/entities/task_entity.dart';
import 'package:agenda_tasks/features/tasks/domain/enums/priority.dart';

void main() {
  group('TaskEntity', () {
    final testDate = DateTime(2026, 2, 3);
    final testCreatedAt = DateTime(2026, 1, 1);

    TaskEntity createTask({
      String id = 'test-id',
      String title = 'Test Task',
      String? description,
      DateTime? date,
      String? time,
      Priority priority = Priority.medium,
      bool isDone = false,
    }) {
      return TaskEntity(
        id: id,
        title: title,
        description: description,
        date: date ?? testDate,
        time: time,
        priority: priority,
        isDone: isDone,
        createdAt: testCreatedAt,
      );
    }

    test('should create a TaskEntity with required fields', () {
      final task = TaskEntity(
        id: 'task-1',
        title: 'My Task',
        date: testDate,
      );

      expect(task.id, 'task-1');
      expect(task.title, 'My Task');
      expect(task.date, testDate);
      expect(task.priority, Priority.medium);
      expect(task.isDone, false);
      expect(task.description, isNull);
      expect(task.time, isNull);
    });

    test('should create a TaskEntity with all fields', () {
      final task = TaskEntity(
        id: 'task-1',
        title: 'My Task',
        description: 'Task description',
        date: testDate,
        time: '14:30',
        priority: Priority.high,
        isDone: true,
        createdAt: testCreatedAt,
        updatedAt: testCreatedAt,
      );

      expect(task.id, 'task-1');
      expect(task.title, 'My Task');
      expect(task.description, 'Task description');
      expect(task.date, testDate);
      expect(task.time, '14:30');
      expect(task.priority, Priority.high);
      expect(task.isDone, true);
      expect(task.createdAt, testCreatedAt);
      expect(task.updatedAt, testCreatedAt);
    });

    group('copyWith', () {
      test('should return a copy with updated title', () {
        final original = createTask();
        final copy = original.copyWith(title: 'Updated Title');

        expect(copy.title, 'Updated Title');
        expect(copy.id, original.id);
        expect(copy.date, original.date);
        expect(copy.priority, original.priority);
      });

      test('should return a copy with updated priority', () {
        final original = createTask(priority: Priority.low);
        final copy = original.copyWith(priority: Priority.high);

        expect(copy.priority, Priority.high);
        expect(copy.title, original.title);
      });

      test('should return a copy with updated isDone', () {
        final original = createTask(isDone: false);
        final copy = original.copyWith(isDone: true);

        expect(copy.isDone, true);
        expect(original.isDone, false);
      });

      test('should return a copy with updated date', () {
        final original = createTask();
        final newDate = DateTime(2026, 3, 15);
        final copy = original.copyWith(date: newDate);

        expect(copy.date, newDate);
        expect(original.date, testDate);
      });

      test('should return identical copy when no arguments provided', () {
        final original = createTask(
          description: 'Test desc',
          time: '10:00',
        );
        final copy = original.copyWith();

        expect(copy.id, original.id);
        expect(copy.title, original.title);
        expect(copy.description, original.description);
        expect(copy.date, original.date);
        expect(copy.time, original.time);
        expect(copy.priority, original.priority);
        expect(copy.isDone, original.isDone);
      });
    });

    group('equality', () {
      test('should be equal when ids are the same', () {
        final task1 = createTask(id: 'same-id', title: 'Task 1');
        final task2 = createTask(id: 'same-id', title: 'Task 2');

        expect(task1, equals(task2));
      });

      test('should not be equal when ids are different', () {
        final task1 = createTask(id: 'id-1', title: 'Same Title');
        final task2 = createTask(id: 'id-2', title: 'Same Title');

        expect(task1, isNot(equals(task2)));
      });

      test('should have same hashCode when ids are the same', () {
        final task1 = createTask(id: 'same-id');
        final task2 = createTask(id: 'same-id');

        expect(task1.hashCode, equals(task2.hashCode));
      });
    });
  });
}
