// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

/// Tests past-task push presentation mapping.
library;

import 'package:flutter_test/flutter_test.dart';
import 'package:scheduler_core/scheduler_core.dart';

import 'package:focus_flow_flutter/models/today_screen_models.dart';

/// Runs past-task push presentation tests.
void main() {
  final now = DateTime.utc(2026, 1, 3, 12);

  test('planned flexible task earlier today shows Push state', () {
    final updatedAt = DateTime.utc(2026, 1, 3, 8, 45);
    final card = TimelineCardModel.fromItem(
      _item(
        start: DateTime.utc(2026, 1, 3, 9),
        end: DateTime.utc(2026, 1, 3, 9, 30),
        updatedAt: updatedAt,
      ),
      now: now,
    );

    expect(card.showPastTaskPushButton, isTrue);
    expect(card.showsQuickActions, isFalse);
    expect(card.expectedUpdatedAt, updatedAt);
    expect(card.pastTaskPushSemanticLabel, 'Push overdue task');
  });

  test(
    'configured timezone offset changes wall-clock labels and positions',
    () {
      final card = TimelineCardModel.fromItem(
        _item(
          start: DateTime.utc(2026, 1, 3, 16),
          end: DateTime.utc(2026, 1, 3, 16, 30),
        ),
        now: DateTime.utc(2026, 1, 3, 17),
        timeZoneOffset: const Duration(hours: -8),
      );

      expect(card.timeText, '8:00 AM - 8:30 AM');
      expect(card.startMinutes, 8 * 60);
      expect(card.endMinutes, 8 * 60 + 30);
      expect(card.showPastTaskPushButton, isTrue);
    },
  );

  test('planned flexible task later today does not show Push state', () {
    final card = TimelineCardModel.fromItem(
      _item(
        start: DateTime.utc(2026, 1, 3, 14),
        end: DateTime.utc(2026, 1, 3, 14, 30),
      ),
      now: now,
    );

    expect(card.showPastTaskPushButton, isFalse);
    expect(card.showsQuickActions, isTrue);
  });

  test('planned flexible task on a previous date shows Push state', () {
    final card = TimelineCardModel.fromItem(
      _item(
        start: DateTime.utc(2026, 1, 2, 14),
        end: DateTime.utc(2026, 1, 2, 14, 30),
      ),
      now: now,
    );

    expect(card.showPastTaskPushButton, isTrue);
    expect(card.showsQuickActions, isFalse);
  });

  test('planned flexible task on a future date does not show Push state', () {
    final card = TimelineCardModel.fromItem(
      _item(
        start: DateTime.utc(2026, 1, 4, 9),
        end: DateTime.utc(2026, 1, 4, 9, 30),
      ),
      now: now,
    );

    expect(card.showPastTaskPushButton, isFalse);
    expect(card.showsQuickActions, isTrue);
  });

  test('completed flexible task in the past does not show Push state', () {
    final card = TimelineCardModel.fromItem(
      _item(
        start: DateTime.utc(2026, 1, 3, 9),
        end: DateTime.utc(2026, 1, 3, 9, 30),
        status: TaskStatus.completed,
      ),
      now: now,
    );

    expect(card.showPastTaskPushButton, isFalse);
    expect(card.showsQuickActions, isFalse);
  });

  test('unsupported task types do not show Push state', () {
    for (final type in [
      TaskType.critical,
      TaskType.inflexible,
      TaskType.locked,
      TaskType.surprise,
      TaskType.freeSlot,
    ]) {
      final card = TimelineCardModel.fromItem(
        _item(
          start: DateTime.utc(2026, 1, 3, 9),
          end: DateTime.utc(2026, 1, 3, 9, 30),
          type: type,
        ),
        now: now,
      );

      expect(card.showPastTaskPushButton, isFalse, reason: type.name);
    }
  });

  test('task without schedule placement does not show Push state', () {
    final card = TimelineCardModel.fromItem(_item(), now: now);

    expect(card.showPastTaskPushButton, isFalse);
  });
}

/// Builds a timeline item for push-state presentation tests.
TodayTimelineItem _item({
  DateTime? start,
  DateTime? end,
  DateTime? updatedAt,
  TaskType type = TaskType.flexible,
  TaskStatus status = TaskStatus.planned,
}) {
  return TodayTimelineItem(
    item: TimelineItem(
      id: 'task-${type.name}-${status.name}',
      displayTitle: 'Task',
      taskType: type,
      projectColorToken: 'project-home',
      backgroundToken: TimelineBackgroundToken.flexible,
      rewardIconToken: TimelineRewardIconToken.medium,
      difficultyIconToken: TimelineDifficultyIconToken.medium,
      showsExplicitTime: true,
      quickActions: const [],
      category: TimelineItemCategory.taskCard,
      start: start,
      end: end,
      updatedAt: updatedAt,
      durationMinutes: start == null || end == null
          ? null
          : end.difference(start).inMinutes,
    ),
    source: TodayTimelineItemSource.task,
    taskStatus: status,
    taskId: 'task-${type.name}-${status.name}',
  );
}
