import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:garden_planner/constance.dart';
import 'package:garden_planner/entities/plant.dart';
import 'package:garden_planner/entities/plant_in_row.dart';
import 'package:garden_planner/repositories/beet.repositories.dart';
import 'package:garden_planner/widgets/content.dart';
import 'package:garden_planner/widgets/content_widgets/control_bar.dart';
import 'package:garden_planner/widgets/content_widgets/dashboard.dart';
import 'package:garden_planner/widgets/content_widgets/footer.dart';
import 'package:garden_planner/widgets/content_widgets/new_beet_row.dart';

import '../helpers/beet_repository_generator.dart';
import '../helpers/plant_generator.dart';

void main() {
  testWidgets('Content widget displays all widgets',
      (WidgetTester tester) async {
    //Arrange
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Content(
            beetRepository: BeetRepositoryGenerator.getBeetRepository(),
          ),
        ),
      ),
    );

    //Assert
    expect(find.byType(Control), findsOneWidget,
        reason: 'Control widget is missing');
    expect(find.byType(Dashboard), findsOneWidget,
        reason: 'Control widget is missing');
    expect(find.byType(NewBeetRow), findsOneWidget,
        reason: 'Control widget is missing');
    expect(find.byType(Footer), findsOneWidget,
        reason: 'Control widget is missing');
  });

  testWidgets('Content widget drop Plant delegate work',
      (WidgetTester tester) async {

    final Plant plant =  PlantGenerator.getPlant();
    final BeetRepository beetrepo = BeetRepositoryGenerator.getBeetRepository();

    //Arrange
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Content(
            beetRepository: beetrepo,
          ),
        ),
      ),
    );

    //Act
    final contentState = tester.state<ContentState>(find.byType(Content));
    contentState.plantDroppedOnRow(0, plant);

    // Assert Plant is Dropped
    expect(beetrepo.getRow(0).plants.length, 1,reason: 'No Plant saved');
    expect(beetrepo.getRow(0).plants[0].id, plant.id,reason: 'Plant drop should be same Plant');
  });

  testWidgets('Content widget new Row', (WidgetTester tester) async {
    final BeetRepository beetrepo = BeetRepositoryGenerator.getBeetRepository();

    //Arrange
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Content(
            beetRepository: beetrepo,
          ),
        ),
      ),
    );

    //Arrange
    for (int i = 1; i < Constance.maxNumberOfRows; i++) {
      await tester.tap(find.text('Neue Reihe'));
      await tester.pumpAndSettle();
    }
    // Assert Plant is Dropped
    expect(find.byType(NewBeetRow), findsNothing,
        reason: 'No Button should appear after max Numbers of row');
    expect(beetrepo.beet.beetRows.length, equals(Constance.maxNumberOfRows),
        reason: 'Rows should be max');
  });

  testWidgets('Content widget drop', (WidgetTester tester) async {
    final BeetRepository beetrepo = BeetRepositoryGenerator.getBeetRepository();

    //Arrange
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Content(
            beetRepository: beetrepo,
          ),
        ),
      ),
    );

    //Act
    final contentState = tester.state<ContentState>(find.byType(Content));
    final newDate = DateTime(2023, 6, 1);
    contentState.newDaySelected(newDate);

    // Assert Date is changed
    expect(contentState.selectedDate, newDate, reason: 'Date not saved');
  });

  testWidgets('Content widget reomove plant', (WidgetTester tester) async {
    final BeetRepository beetrepo = BeetRepositoryGenerator.getBeetRepository();

    //Arrange
    beetrepo.addPlantToRowById(0, PlantGenerator.getPlant());
    beetrepo.addPlantToRowById(0, PlantGenerator.getPlant2());

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Content(
            beetRepository: beetrepo,
          ),
        ),
      ),
    );

    //Act
    final contentState = tester.state<ContentState>(find.byType(Content));
    contentState.plantRemovedFromRow(
        0, PlantInRow(position: 1, plant: PlantGenerator.getPlant()));

    // Assert Date is changed
    expect(beetrepo.getRow(0).plants.length, 1,
        reason: 'plants should be removed');
  });
}