import 'package:drift/drift.dart' show Value;
import 'package:flutter_test/flutter_test.dart';
import 'package:tane/data/variety_repository.dart';
import 'package:tane/db/database.dart';
import 'package:tane/domain/crop_calendar.dart';
import 'package:tane/state/inventory_cubit.dart';

import '../support/test_support.dart';

/// The aggregate crop calendar: `watchCalendar` surfaces every variety with a
/// recorded phase, and the inventory carries sow-months for the "this month"
/// filter.
void main() {
  late AppDatabase db;
  setUp(() => db = newTestDatabase());
  tearDown(() => db.close());

  test('watchCalendar emits varieties with a recorded phase, masks intact',
      () async {
    final repo = newTestRepository(db);
    final tomato = await repo.addQuickVariety(label: 'Tomate rosa');
    await repo.updateVariety(
      id: tomato,
      sowMonths: Value(monthsToMask([2, 3])), // Feb, Mar
      seedHarvestMonths: Value(monthsToMask([8])), // Aug
    );
    // A variety with no calendar at all is excluded.
    await repo.addQuickVariety(label: 'Sin calendario');

    final entries = await repo.watchCalendar().first;
    expect(entries, hasLength(1));
    final e = entries.single;
    expect(e.label, 'Tomate rosa');
    expect(maskHasMonth(e.sowMonths, 3), isTrue);
    expect(maskHasMonth(e.sowMonths, 5), isFalse);
    expect(maskHasMonth(e.seedHarvestMonths, 8), isTrue);
  });

  test('the inventory list carries sow-months', () async {
    final repo = newTestRepository(db);
    final id = await repo.addQuickVariety(label: 'Lechuga');
    await repo.updateVariety(id: id, sowMonths: Value(monthsToMask([9])));

    final items = await repo.watchInventory().first;
    expect(items.single.sowMonths, monthsToMask([9]));
  });

  test('the sow-this-month filter keeps only what sows in the pinned month', () {
    const march = 3;
    final sowsInMarch = _item('a', monthsToMask([3, 4]));
    final sowsInJune = _item('b', monthsToMask([6]));
    final noCalendar = _item('c', null);
    final state = InventoryState(
      items: [sowsInMarch, sowsInJune, noCalendar],
      sowThisMonthOnly: true,
      filterMonth: march,
      loading: false,
    );
    expect(state.visibleItems.map((i) => i.id), ['a']);
    expect(state.hasSowCalendar, isTrue);
  });
}

VarietyListItem _item(String id, int? sowMonths) =>
    VarietyListItem(id: id, label: id, sowMonths: sowMonths);
