import '../contracts/library.dart';
import '../../shared/utils/app_logger.dart';

EmbyRawMediaStream? findVideoStream(EmbyRawMediaSource source) {
  final streams = source.MediaStreams;
  if (streams == null) return null;
  for (final stream in streams) {
    if (stream.Type == 'Video') return stream;
  }
  return null;
}

final RegExp _dvNameTokenRegex = RegExp(r'\bdv\b', caseSensitive: false);

bool _nameLooksLikeDolbyVision(String? name) {
  if (name == null || name.isEmpty) return false;
  final lower = name.toLowerCase();
  if (lower.contains('dovi')) return true;
  if (lower.contains('dolby vision')) return true;
  if (_dvNameTokenRegex.hasMatch(name)) return true;
  return false;
}

bool _nameLooksLikeHdr(String? name) {
  if (name == null || name.isEmpty) return false;
  final lower = name.toLowerCase();
  if (lower.contains('hdr')) return true;
  return _nameLooksLikeDolbyVision(name);
}

bool isDolbyVision(EmbyRawMediaSource source) {
  final video = findVideoStream(source);
  final hasVideoStream = video != null;
  final rawRange = video?.extra['VideoRange'] as String? ?? '';
  final rawRangeType = video?.extra['VideoRangeType'] as String? ?? '';
  final rawCodec = video?.Codec ?? '';
  final rawDisplayTitle = video?.DisplayTitle ?? '';
  final rawTitle = video?.Title ?? '';

  bool result;
  if (!hasVideoStream) {
    result = false;
  } else {
    final range = rawRange.toLowerCase();
    final rangeType = rawRangeType.toLowerCase();
    final codec = rawCodec.toLowerCase();
    final displayTitle = rawDisplayTitle.toLowerCase();
    final title = rawTitle.toLowerCase();
    result =
        rangeType.contains('dovi') ||
        rangeType.contains('dolby') ||
        range.contains('dovi') ||
        range.contains('dolby') ||
        codec.contains('dvh') ||
        codec.contains('dovi') ||
        displayTitle.contains('dovi') ||
        displayTitle.contains('dolby vision') ||
        title.contains('dovi') ||
        title.contains('dolby vision');
  }

  String fmt(String v) => v.isEmpty ? '<empty>' : v;
  final sourceId = source.Id ?? '<null>';
  AppLogger.debug(
    'DVDetect',
    'source=$sourceId hasVideo=$hasVideoStream '
        'VideoRange="${fmt(rawRange)}" VideoRangeType="${fmt(rawRangeType)}" '
        'Codec="${fmt(rawCodec)}" DisplayTitle="${fmt(rawDisplayTitle)}" '
        'Title="${fmt(rawTitle)}" -> isDV=$result',
  );

  if (!result) {
    final name = source.Name;
    final fallback = _nameLooksLikeDolbyVision(name);
    if (fallback) {
      AppLogger.debug(
        'DVDetect',
        'name fallback hit: name="${name ?? '<null>'}" -> isDV=true',
      );
      result = true;
    } else {
      AppLogger.debug(
        'DVDetect',
        'name fallback miss: name="${name ?? '<null>'}"',
      );
    }
  }

  return result;
}

bool isHdr(EmbyRawMediaSource source) {
  final video = findVideoStream(source);
  bool result;
  if (video == null) {
    result = false;
  } else {
    final range = (video.extra['VideoRange'] as String? ?? '').toLowerCase();
    final rangeType = (video.extra['VideoRangeType'] as String? ?? '')
        .toLowerCase();
    result =
        range.contains('hdr') ||
        range.contains('dovi') ||
        rangeType.contains('hdr') ||
        rangeType.contains('dovi');
  }

  if (!result) {
    final name = source.Name;
    final fallback = _nameLooksLikeHdr(name);
    if (fallback) {
      AppLogger.debug(
        'HDRDetect',
        'name fallback hit: name="${name ?? '<null>'}" -> isHdr=true',
      );
      result = true;
    } else {
      AppLogger.debug(
        'HDRDetect',
        'name fallback miss: name="${name ?? '<null>'}"',
      );
    }
  }

  return result;
}

double getFrameRate(EmbyRawMediaSource source) {
  final video = findVideoStream(source);
  if (video == null) return 0;
  return (video.extra['RealFrameRate'] as num?)?.toDouble() ??
      (video.extra['AverageFrameRate'] as num?)?.toDouble() ??
      0;
}
