import 'dart:async';

import 'package:fvp/mdk.dart' as mdk;

import '../../shared/utils/app_logger.dart';
import 'media_capability_analyzer.dart';


class MediaProbeService {
  static final MediaProbeService instance = MediaProbeService._();
  MediaProbeService._();

  static const _tag = 'MediaProbe';

  final Map<String, ProbeResult> _cache = {};

  Future<ProbeResult?> probe(
    String url, {
    Duration timeout = const Duration(seconds: 5),
  }) async {
    final cached = _cache[url];
    if (cached != null) {
      AppLogger.debug(_tag, 'probe: cache hit url=${_truncate(url)}');
      return cached;
    }

    AppLogger.debug(_tag, 'probe: start url=${_truncate(url)}');

    mdk.Player? player;
    try {
      player = mdk.Player()
        ..setProperty('avio.reconnect', '1')
        ..setProperty('avformat.extension_picky', '0')
        ..setProperty('avformat.allowed_segment_extensions', 'ALL');
      player.media = url;

      final ret = await player.prepare().timeout(timeout, onTimeout: () => -10);

      ProbeResult? result;
      if (ret >= 0) {
        final video = player.mediaInfo.video;
        if (video != null && video.isNotEmpty) {
          final codec = video.first.codec;
          result = ProbeResult(
            videoCodec: codec.codec.isNotEmpty ? codec.codec : null,
          );
        }
      } else {
        AppLogger.warn(
          _tag,
          'probe: prepare failed ret=$ret url=${_truncate(url)}',
        );
      }

      if (result != null) {
        _cache[url] = result;
        AppLogger.debug(
          _tag,
          'probe: success url=${_truncate(url)} codec=${result.videoCodec}',
        );
      }

      return result;
    } catch (e) {
      AppLogger.warn(_tag, 'probe: error url=${_truncate(url)}', e);
      return null;
    } finally {
      player?.dispose();
    }
  }

  static String _truncate(String url) {
    return url.length > 50 ? '${url.substring(0, 50)}...' : url;
  }
}
