

import 'dart:async';

import '../../../core/contracts/playback.dart';
import '../../../core/domain/ports/emby_gateway.dart';
import '../../../shared/utils/app_logger.dart';

typedef PlaybackReportPayloadBuilder =
    PlaybackReportPayload Function({required bool isPaused, String? eventName});

class EmbyPlaybackReporter {
  EmbyPlaybackReporter({
    required EmbyGateway gateway,
    required AuthedRequestContext context,
    this.enabled = true,
  }) : _gateway = gateway,
       _context = context;

  static const _tag = 'Reporter';

  final EmbyGateway _gateway;
  final AuthedRequestContext _context;


  final bool enabled;

  bool _startedReported = false;
  bool _stoppedReported = false;
  Timer? _progressTimer;

  bool get startedReported => _startedReported;
  bool get stoppedReported => _stoppedReported;

  Future<void> reportStarted(PlaybackReportPayload payload) async {
    if (!enabled) return;
    if (_startedReported) return;
    _startedReported = true;
    try {
      await _gateway.reportPlaybackStarted(ctx: _context, payload: payload);
    } catch (e) {
      AppLogger.warn(_tag, 'Start report failed', e);
    }
  }

  Future<void> reportProgress(PlaybackReportPayload payload) async {
    if (!_startedReported) return;
    try {
      await _gateway.reportPlaybackProgress(ctx: _context, payload: payload);
    } catch (e) {
      AppLogger.warn(_tag, 'Progress report failed', e);
    }
  }

  Future<void> reportStopped(PlaybackReportPayload payload) async {
    if (!enabled) return;
    if (!_startedReported) {
      AppLogger.debug(_tag, 'stop report skipped: start not reported');
      return;
    }
    if (_stoppedReported) {
      AppLogger.debug(_tag, 'stop report skipped: already stopped');
      return;
    }
    _stoppedReported = true;
    _progressTimer?.cancel();
    final sw = Stopwatch()..start();
    try {
      await _gateway.reportPlaybackStopped(ctx: _context, payload: payload);
      AppLogger.debug(_tag, 'stop report ok in ${sw.elapsedMilliseconds}ms');
    } catch (e) {
      AppLogger.warn(
        _tag,
        'Stop report failed after ${sw.elapsedMilliseconds}ms',
        e,
      );
    }
  }

  void startProgressTimer(PlaybackReportPayloadBuilder payloadBuilder) {
    if (!enabled) return;
    if (_progressTimer != null) return;
    _progressTimer = Timer.periodic(const Duration(seconds: 8), (_) {
      if (_startedReported && !_stoppedReported) {
        unawaited(
          reportProgress(
            payloadBuilder(isPaused: false, eventName: 'TimeUpdate'),
          ),
        );
      }
    });
  }

  void reset() {
    _progressTimer?.cancel();
    _progressTimer = null;
    _startedReported = false;
    _stoppedReported = false;
  }

  void dispose() {
    _progressTimer?.cancel();
    _progressTimer = null;
  }
}
