import 'package:flutter_test/flutter_test.dart';
import 'package:tane/db/database.dart';
import 'package:tane/db/enums.dart';

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

/// A Plantare is a reproduction commitment (data-model §2.7): create it, list
/// it, mark it returned/forgiven, and remove it (soft-delete).
void main() {
  late AppDatabase db;
  setUp(() => db = newTestDatabase());
  tearDown(() => db.close());

  test('records a commitment and lists it (globally and per variety)', () async {
    final repo = newTestRepository(db);
    final vid = await repo.addQuickVariety(label: 'Tomate rosa');
    final id = await repo.createPlantare(
      direction: PlantareDirection.iReturn,
      varietyId: vid,
      counterparty: 'Ana',
      owedDescription: 'un puñado la próxima temporada',
    );

    final all = await repo.watchPlantares().first;
    expect(all, hasLength(1));
    expect(all.single.id, id);
    expect(all.single.direction, PlantareDirection.iReturn);
    expect(all.single.counterparty, 'Ana');
    expect(all.single.status, PlantareStatus.open);
    expect(all.single.madeOn, greaterThan(0));

    final forVariety = await repo.watchPlantaresForVariety(vid).first;
    expect(forVariety.single.id, id);
    // A different variety has none.
    final other = await repo.addQuickVariety(label: 'Judía');
    expect(await repo.watchPlantaresForVariety(other).first, isEmpty);
  });

  test('marking it returned stamps the settle time; forgiving keeps it settled',
      () async {
    final repo = newTestRepository(db);
    final id = await repo.createPlantare(direction: PlantareDirection.owedToMe);

    await repo.setPlantareStatus(id, PlantareStatus.returned);
    var row = (await repo.watchPlantares().first).single;
    expect(row.status, PlantareStatus.returned);
    expect(row.settledOn, isNotNull);

    // Reopening clears the settle stamp.
    await repo.setPlantareStatus(id, PlantareStatus.open);
    row = (await repo.watchPlantares().first).single;
    expect(row.status, PlantareStatus.open);
    expect(row.settledOn, isNull);
  });

  test('deleting a commitment tombstones it (drops from the list)', () async {
    final repo = newTestRepository(db);
    final id = await repo.createPlantare(direction: PlantareDirection.iReturn);
    expect(await repo.watchPlantares().first, hasLength(1));
    await repo.deletePlantare(id);
    expect(await repo.watchPlantares().first, isEmpty);
  });

  test('commitments survive a backup round-trip (in exportInventory/import)',
      () async {
    final repoA = newTestRepository(db);
    final vid = await repoA.addQuickVariety(label: 'Maíz');
    await repoA.createPlantare(
      direction: PlantareDirection.iReturn,
      varietyId: vid,
      counterparty: 'Colectivo semillero',
      owedDescription: 'una mazorca',
    );

    final snapshot = await repoA.exportInventory();
    expect(snapshot.plantares, hasLength(1));

    final dbB = newTestDatabase();
    addTearDown(dbB.close);
    final repoB = newTestRepository(dbB);
    await repoB.importInventory(snapshot);
    final onB = await repoB.watchPlantares().first;
    expect(onB.single.counterparty, 'Colectivo semillero');
    expect(onB.single.owedDescription, 'una mazorca');
  });
}
