// Tests for the two-up spread layout foundation (F2/F3).

import 'dart:ui' show Size;

import 'package:flutter_test/flutter_test.dart';

import 'package:badnote/editor/layout/double_page_layout.dart';
import 'package:badnote/editor/pdf/pdf_document_source.dart';

class _Src implements PageDocumentSource {
  _Src(this._sizes);
  final List<Size> _sizes;
  @override
  int get pageCount => _sizes.length;
  @override
  Size pageSize(int index) => _sizes[index];
}

void main() {
  group('pairIntoRows', () {
    test('pairs from 0 by default', () {
      expect(pairIntoRows(4), [
        [0, 1],
        [2, 3],
      ]);
    });

    test('trailing odd page gets a single-page row', () {
      expect(pairIntoRows(5), [
        [0, 1],
        [2, 3],
        [4],
      ]);
    });

    test('coverAlone puts page 0 alone, then pairs', () {
      expect(pairIntoRows(5, coverAlone: true), [
        [0],
        [1, 2],
        [3, 4],
      ]);
    });

    test('edge counts', () {
      expect(pairIntoRows(0), isEmpty);
      expect(pairIntoRows(1), [
        [0],
      ]);
      expect(pairIntoRows(1, coverAlone: true), [
        [0],
      ]);
      expect(pairIntoRows(2, coverAlone: true), [
        [0],
        [1],
      ]);
    });
  });

  group('spreadRowHeights', () {
    test('row height is the tallest page at half column width', () {
      // page0 600x800 (aspect 800/600), page1 600x400. At column 600 → half 300.
      // page0 fit = 300 * 800/600 = 400; page1 fit = 300 * 400/600 = 200.
      final src = _Src([const Size(600, 800), const Size(600, 400)]);
      final rows = pairIntoRows(2);
      expect(spreadRowHeights(src, 600, rows), [400.0]); // max(400,200)
    });

    test('single-page row uses that page only', () {
      final src = _Src([const Size(400, 800)]);
      final rows = pairIntoRows(1);
      // half = 150; fit = 150 * 800/400 = 300.
      expect(spreadRowHeights(src, 300, rows), [300.0]);
    });

    test('non-positive width contributes 0', () {
      final src = _Src([const Size(0, 800), const Size(400, 400)]);
      final rows = pairIntoRows(2); // [[0,1]]
      // page0 → 0; page1 half=150 fit=150*400/400=150 → max 150.
      expect(spreadRowHeights(src, 300, rows), [150.0]);
    });
  });

  group('spreadStackMetrics composes with windowing', () {
    test('rows stack vertically; visibleRange selects visible rows', () {
      // 6 portrait pages 600x800 → 3 rows; at column 600 each row 400 tall.
      final src = _Src(List.filled(6, const Size(600, 800)));
      final m = spreadStackMetrics(src, 600, gap: 0);
      expect(m.pageCount, 3); // 3 ROWS
      expect(m.totalExtent, closeTo(1200, 1e-9)); // 3 * 400
      // viewport [350,850): row0 [0,400), row1 [400,800), row2 [800,1200).
      // first bottom>350 → row0; last top<850 → row2.
      expect(m.visibleRange(350, 500).first, 0);
      expect(m.visibleRange(350, 500).last, 2);
    });
  });
}
