import 'dart:typed_data';

import 'package:commons_core/commons_core.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:tane/data/species_repository.dart';
import 'package:tane/data/variety_repository.dart';
import 'package:tane/db/database.dart';

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

/// A starter catalog, including a name ("Calabaza") shared across two species
/// so the ambiguous case can be exercised end-to-end.
const _seeds = [
  SpeciesSeed(
    scientificName: 'Zea mays',
    family: 'Poaceae',
    commonNames: {
      'es': ['Maíz'],
      'en': ['Maize', 'Corn'],
    },
  ),
  SpeciesSeed(
    scientificName: 'Solanum lycopersicum',
    family: 'Solanaceae',
    commonNames: {
      'es': ['Tomate'],
      'en': ['Tomato'],
    },
  ),
  SpeciesSeed(
    scientificName: 'Cucurbita pepo',
    family: 'Cucurbitaceae',
    commonNames: {
      'es': ['Calabaza', 'Calabacín'],
    },
  ),
  SpeciesSeed(
    scientificName: 'Cucurbita maxima',
    family: 'Cucurbitaceae',
    commonNames: {
      'es': ['Calabaza'],
    },
  ),
];

void main() {
  late AppDatabase db;
  late VarietyRepository repo;

  setUp(() async {
    db = newTestDatabase();
    repo = newTestRepository(db);
    await SpeciesRepository(db, idGen: IdGen()).seedBundled(_seeds);
  });
  tearDown(() => db.close());

  Future<Variety> only() async => db.select(db.varieties).getSingle();

  test('addQuickVariety auto-links the species named in the label', () async {
    await repo.addQuickVariety(label: 'Maíz de la abuela');
    final v = await only();
    final species = await (db.select(
      db.species,
    )..where((s) => s.id.equals(v.speciesId!))).getSingle();
    expect(species.scientificName, 'Zea mays');
    // Category is prefilled from the species family.
    expect(v.category, 'Poaceae');
  });

  test('auto-classification is accent-insensitive', () async {
    await repo.addQuickVariety(label: 'Maiz dulce'); // typed without the accent
    final v = await only();
    expect(v.speciesId, isNotNull);
    expect(v.category, 'Poaceae');
  });

  test('an explicit category is kept, species still links', () async {
    await repo.addQuickVariety(label: 'Tomate cherry', category: 'Mi huerto');
    final v = await only();
    expect(v.speciesId, isNotNull);
    expect(v.category, 'Mi huerto'); // not overwritten by the family
  });

  test('an unknown label leaves the variety unclassified', () async {
    await repo.addQuickVariety(label: 'Girasol gigante');
    final v = await only();
    expect(v.speciesId, isNull);
    expect(v.category, isNull);
  });

  test('an ambiguous name is left for the grower to disambiguate', () async {
    await repo.addQuickVariety(label: 'Calabaza de invierno');
    final v = await only();
    expect(v.speciesId, isNull);
    expect(v.category, isNull);
  });

  test('nameDraft auto-classifies when the draft has no species yet', () async {
    final id = await repo.addDraftVariety(Uint8List.fromList([1, 2, 3]));
    await repo.nameDraft(id, 'Tomate rosa');
    final v = await only();
    expect(v.isDraft, isFalse);
    expect(v.label, 'Tomate rosa');
    expect(v.speciesId, isNotNull);
    expect(v.category, 'Solanaceae');
  });
}
