import '../api/garden_api.service.dart';
import '../entities/beet.dart';
import '../entities/beet_entry_return.dart';
import '../entities/beet_row.dart';
import '../entities/plant.dart';
import 'beet_row.service.dart';
import 'plant.service.dart';

class BeetService {
  void addPlantToRowById(final Beet beet, final BeetRowService rowService,
      final int rowId, final Plant plant) {
    final BeetRow row = rowService.getRowById(beet, rowId);
    rowService.addPlant(row, plant);
  }

  void addNewRow(final Beet beet) {
    beet.beetRows.add(BeetRow(beet.beetRows.length));
  }

  double getMaxHorizontalSpaceOfRows(
      final BeetRowService beetRowService, final Beet beet) {
    double maxHorizontalSpace = 0;

    for (final BeetRow beetRow in beet.beetRows) {
      final double horizontalSpace =
          beetRowService.getTotalHorizontalSpace(beetRow);

      if (horizontalSpace > maxHorizontalSpace) {
        maxHorizontalSpace = horizontalSpace;
      }
    }

    return maxHorizontalSpace;
  }

  bool isActionNeeded(final BeetRowService beetRowService,
      final PlantService plantService, final Beet beet, final DateTime date) {
    final bool isActionNeeded = beet.beetRows.any((final BeetRow row) =>
        beetRowService.isActionNeeded(plantService, row, date));

    return isActionNeeded;
  }

  List<double> getVerticalPlantingSpace(
      final BeetRowService beetRowService, final Beet beet) {
    double preUsedSpace = 0;
    final List<double> spaceElements = [];

    for (final BeetRow row in beet.beetRows) {
      final double maxVerticalSpace =
          beetRowService.getMaxVerticalSpaceOfPlantInTheRow(row);
      var position = preUsedSpace + (maxVerticalSpace / 2);

      spaceElements.add(position);
      preUsedSpace += maxVerticalSpace;
    }

    return spaceElements;
  }

  Future<String> saveBeet(
      final GardenApiService apiService, final Beet beet) async {
    return apiService.saveBeet(beet);
  }

  Future<void> loadBeet(final GardenApiService apiService,
      final BeetRowService rowService, final Beet beet) async {
    final List<BeetApiEntryReturn> beetEntries = await apiService.getBeet();

    for (final BeetApiEntryReturn beetEntry in beetEntries) {
      _addLoadedPlant(beet, rowService, beetEntry.plant, beetEntry.beetRow);
    }
  }

  void _addLoadedPlant(final Beet beet, final BeetRowService rowService,
      final Plant plant, final int row) {
    while (beet.beetRows.length <= row) {
      addNewRow(beet);
    }

    rowService.addPlant(beet.beetRows[row], plant);
  }
}
