import 'package:flutter_test/flutter_test.dart';
import 'package:garden_planner/entities/beet.dart';
import 'package:garden_planner/entities/plant.dart';
import 'package:garden_planner/logic/beet.service.dart';
import 'package:garden_planner/logic/beet_row.service.dart';
import 'package:garden_planner/logic/plant.service.dart';

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

void main() {
  test('BeetService Add Row should increase the Rows', () {
    // Arrange
    final Beet beet = Beet();
    final BeetService beetService = BeetService();
    // Act
    beetService.addNewRow(beet);

    // Assert
    // expect(beet.beetrows, equals(2));
  });

  test('BeetService addPlantToRowById should work', () {
    // Arrange
    final BeetService beetService = BeetService();
    final Beet beet = Beet();
    final BeetRowService beetRowService = BeetRowService();
    final Plant plant = PlantGenerator.getPlant();
    final Plant plant2 = PlantGenerator.getPlant2();

    // Act
    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    beetService.addPlantToRowById(beet, beetRowService, 0, plant2);

    // row existiert nicht
    expect(() => beetService.addPlantToRowById(beet, beetRowService, 1, plant),
        throwsStateError);

    // Assert
    expect(beet.beetRows.length, equals(1), reason: 'It should be ine row');
    expect(beet.beetRows[0].plants.length, equals(2),
        reason: 'it should be plants two rows in the row');
    expect(beet.beetRows[0].plants[0].id, equals(plant.id),
        reason: 'Id is not right for plant1');
    expect(beet.beetRows[0].plants[1].id, equals(plant2.id),
        reason: 'Id is not right for plant 2');
  });

  test('BeetService addNewRow should work', () {
    // Arrange
    final BeetService beetService = BeetService();
    final Beet beet = Beet();

    // Act
    beetService.addNewRow(beet);
    beetService.addNewRow(beet);

    // Assert
    expect(beet.beetRows.length, equals(3), reason: 'it should be 3 rows');
    expect(beet.beetRows[0].id, equals(0), reason: 'Row 1 id should be 0');
    expect(beet.beetRows[1].id, equals(1), reason: 'Row 2 id should be 1');
    expect(beet.beetRows[2].id, equals(2), reason: 'Row 3 id should be 2');
  });

  test('BeetService getMaxHorizontalSpace should work', () {
    // Arrange
    final BeetService beetService = BeetService();
    final Beet beet = Beet();
    final BeetRowService beetRowService = BeetRowService();
    final Plant plant = PlantGenerator.getPlant();
    final Plant plant2 = PlantGenerator.getPlant2();

    beetService.addNewRow(beet);

    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    beetService.addPlantToRowById(beet, beetRowService, 1, plant);

    beetService.addPlantToRowById(beet, beetRowService, 1, plant2);

    // Act
    var getMaxHorizontalSpace =
        beetService.getMaxHorizontalSpaceOfRows(beetRowService, beet);

    // Assert
    // row 1 = 0,6 + 0,6
    // row 2 = 0.25 + 0.25
    expect(getMaxHorizontalSpace, equals(1.2),
        reason: 'Horizontal space should be 1.2');
  });

  test('BeetService isActionNeeded should work', () {
    // Arrange
    final BeetService beetService = BeetService();
    final Beet beet = Beet();
    final BeetRowService beetRowService = BeetRowService();
    final PlantService plantService = PlantService();

    final Plant plant = PlantGenerator.getPlant();

    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    // Act
    var actionShouldBeTrue = beetService.isActionNeeded(
        beetRowService, plantService, beet, DateTime(2023, 05, 01));

    var actionShouldBeFalseBecauseNoEntry = beetService.isActionNeeded(
        beetRowService, plantService, beet, DateTime(2023, 07, 01));
    var actionShouldBeFalse = beetService.isActionNeeded(
        beetRowService, plantService, beet, DateTime(2023, 10, 01));

    // Assert
    expect(actionShouldBeTrue, equals(true), reason: 'Action should be true');
    expect(actionShouldBeFalse, equals(false),
        reason: 'action should be false because no entry');
    expect(actionShouldBeFalseBecauseNoEntry, equals(false),
        reason: 'Action should be false');
  });

  test('BeetService getVerticalSpaceValue should work', () {
    // Arrange
    final BeetService beetService = BeetService();
    final Beet beet = Beet();
    final BeetRowService beetRowService = BeetRowService();
    final Plant plant = PlantGenerator.getPlant();
    final Plant plant2 = PlantGenerator.getPlant2();

    beetService.addNewRow(beet);

    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    beetService.addPlantToRowById(beet, beetRowService, 0, plant);

    beetService.addPlantToRowById(beet, beetRowService, 1, plant);

    beetService.addPlantToRowById(beet, beetRowService, 1, plant2);

    // Act
    var getVerticalSpaceValue =
        beetService.getVerticalPlantingSpace(beetRowService, beet);

    // Assert
    //  Every Row takes the half Vertical Space, because the Plant will be placed in the middle
    // for the second row, its the hole space of the previews and the half of the actual row
    // in both rows is the biggest space 0.8
    var row1 = (0.8 / 2);
    var row2 = (0.8 + (0.8 / 2));

    expect(getVerticalSpaceValue, equals([row1, row2]),
        reason: 'Vertical space is not right');
  });

  // DB Tests will be in next Release
}
