import 'package:flutter_test/flutter_test.dart';
import 'package:gametime/application/application.dart';
import 'package:watch_bridge_contract/watch_bridge_contract.dart';

void main() {
  test('builds active timer notification content', () {
    final content = buildSessionNotificationContent(
      _projection(
        exerciseName: 'Squats bulgares',
        dominantTimer: _timer(label: 'Chrono étape', accumulatedMs: 134000),
      ),
    );

    expect(content.title, 'Squats bulgares');
    expect(content.primaryLine, '02:14');
    expect(content.secondaryLine, 'Série 2/4');
  });

  test('builds manual score notification content', () {
    final content = buildSessionNotificationContent(
      _projection(
        exerciseName: 'Lancers francs',
        hasManualScore: true,
        currentManualScoreValue: 8,
      ),
    );

    expect(content.title, 'Lancers francs');
    expect(content.primaryLine, 'Série 2/4 · 8');
  });

  test('builds rest notification content with next exercise', () {
    final now = DateTime.utc(2026, 7, 26, 10);
    final content = buildSessionNotificationContent(
      _projection(
        phase: WatchSessionPhase.restRunning,
        exerciseName: 'Squats',
        nextExerciseName: 'Fentes',
        dominantTimer: _timer(
          kind: WatchTimerKind.rest,
          displayMode: WatchTimerDisplayMode.countdown,
          runState: WatchTimerRunState.running,
          accumulatedMs: 10000,
          targetMs: 60000,
          startedAtEpochMs: now.millisecondsSinceEpoch,
        ),
      ),
      now: now.add(const Duration(seconds: 5)),
    );

    expect(content.title, 'Repos');
    expect(content.primaryLine, '00:45 restant · Ensuite : Fentes');
  });

  test('prefixes paused content without ticking', () {
    final content = buildSessionNotificationContent(
      _projection(
        phase: WatchSessionPhase.paused,
        dominantTimer: _timer(
          runState: WatchTimerRunState.paused,
          accumulatedMs: 42000,
        ),
      ),
      now: DateTime.utc(2026, 7, 26, 10),
    );

    expect(content.primaryLine, 'En pause · 00:42');
  });

  test('falls back to current step name without timer or score', () {
    final content = buildSessionNotificationContent(
      _projection(stepName: 'Gainage'),
    );

    expect(content.primaryLine, 'Gainage');
  });
}

WatchSessionProjection _projection({
  WatchSessionPhase phase = WatchSessionPhase.running,
  String exerciseName = 'Pompes',
  String? stepName,
  WatchTimerProjection? dominantTimer,
  bool hasManualScore = false,
  double? currentManualScoreValue,
  String? nextExerciseName,
}) {
  return WatchSessionProjection(
    deviceSessionId: 'session-1',
    revision: 1,
    projectedAtEpochMs: DateTime.utc(2026, 7, 26, 10).millisecondsSinceEpoch,
    phase: phase,
    phoneReachable: true,
    seriesIndex: 2,
    seriesTotal: 4,
    exerciseName: exerciseName,
    stepName: stepName,
    dominantTimer: dominantTimer,
    primaryAction: WatchPrimaryAction.pauseSession,
    nextExerciseName: nextExerciseName,
    hasManualScore: hasManualScore,
    currentManualScoreValue: currentManualScoreValue,
    canDecrementScore: (currentManualScoreValue ?? 0) > 0,
  );
}

WatchTimerProjection _timer({
  WatchTimerKind kind = WatchTimerKind.step,
  String label = 'Chrono',
  WatchTimerDisplayMode displayMode = WatchTimerDisplayMode.elapsed,
  WatchTimerRunState runState = WatchTimerRunState.stopped,
  int accumulatedMs = 0,
  int? startedAtEpochMs,
  int? targetMs,
}) {
  return WatchTimerProjection(
    kind: kind,
    label: label,
    displayMode: displayMode,
    runState: runState,
    referenceEpochMs: DateTime.utc(2026, 7, 26, 10).millisecondsSinceEpoch,
    accumulatedMs: accumulatedMs,
    startedAtEpochMs: startedAtEpochMs,
    targetMs: targetMs,
  );
}
