import '../contracts/danmaku.dart';


const int kDefaultHeatmapMinComments = 50;


const int kDefaultHeatmapBucketCount = 200;


class DanmakuHeatmapData {
  final List<double> buckets;
  final int bucketCount;
  final int totalComments;
  final int maxCount;
  final bool visible;

  const DanmakuHeatmapData({
    required this.buckets,
    required this.bucketCount,
    required this.totalComments,
    required this.maxCount,
    required this.visible,
  });

  static const empty = DanmakuHeatmapData(
    buckets: <double>[],
    bucketCount: 0,
    totalComments: 0,
    maxCount: 0,
    visible: false,
  );
}


DanmakuHeatmapData computeHeatmap({
  required List<DanmakuComment> comments,
  required double durationSec,
  int bucketCount = kDefaultHeatmapBucketCount,
  int minComments = kDefaultHeatmapMinComments,
}) {
  if (bucketCount <= 0) return DanmakuHeatmapData.empty;
  if (durationSec <= 0) return DanmakuHeatmapData.empty;

  final counts = List<int>.filled(bucketCount, 0);
  int total = 0;
  for (final c in comments) {
    final t = c.time;
    if (t < 0 || t > durationSec) continue;
    var idx = (t / durationSec * bucketCount).floor();
    if (idx >= bucketCount) idx = bucketCount - 1;
    if (idx < 0) idx = 0;
    counts[idx]++;
    total++;
  }

  if (total < minComments) {
    return DanmakuHeatmapData(
      buckets: const <double>[],
      bucketCount: bucketCount,
      totalComments: total,
      maxCount: 0,
      visible: false,
    );
  }

  var maxCount = 0;
  for (final v in counts) {
    if (v > maxCount) maxCount = v;
  }
  if (maxCount <= 0) {
    return DanmakuHeatmapData(
      buckets: const <double>[],
      bucketCount: bucketCount,
      totalComments: total,
      maxCount: 0,
      visible: false,
    );
  }

  final buckets = List<double>.generate(
    bucketCount,
    (i) => counts[i] / maxCount,
    growable: false,
  );

  return DanmakuHeatmapData(
    buckets: buckets,
    bucketCount: bucketCount,
    totalComments: total,
    maxCount: maxCount,
    visible: true,
  );
}


List<double> downsampleHeatmap(List<double> buckets, int targetCount) {
  if (buckets.isEmpty || targetCount <= 0) return const <double>[];
  if (targetCount >= buckets.length) return buckets;
  final out = List<double>.filled(targetCount, 0.0);
  final src = buckets.length;
  for (var i = 0; i < targetCount; i++) {
    final start = (i * src / targetCount).floor();
    final end = ((i + 1) * src / targetCount).floor().clamp(start + 1, src);
    var m = 0.0;
    for (var j = start; j < end; j++) {
      if (buckets[j] > m) m = buckets[j];
    }
    out[i] = m;
  }
  return out;
}
