import 'package:ernaehrung/helper/format_helper.dart';
import 'package:ernaehrung/models/food.dart';
import 'package:ernaehrung/pages/nav_pages/subpages/progress_page/sub_components/charts/sub_components/tabs/timespan_tabs.dart';
import 'package:ernaehrung/services/statistics.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';

// TO RUN TESTS COMMENT initBoxes() (services/statistics.dart line 21) out -> HIVE behavior is tested in other tests

late DataService dataService;
Future<void> main() async {
  await dotenv.load(fileName: ".env");

  setUp(() async {
    dataService = DataService.instance;
  });

  tearDown(() async {
    //await Hive.close(); // Close Hive at the end of tests

  });

  getTimestampFromNow(){
    DateTime now = DateTime.now();
    return now.millisecondsSinceEpoch.toInt() ~/ 1000;
  }

  getTimeStampForDateTime(DateTime date){
    return date.millisecondsSinceEpoch.toInt() ~/ 1000;
  }

  getFoodListValid(){
    // 1500kcal
    return [
      Food(167511, "Testfood","",300,0,0,0,0,0),
      Food(167512, "TestfoodTestfoodTestfoodTestfood","",300,0,0,0,0,0),
      Food(167512, "","",300,0,0,0,0,0),
      Food(167512, "","",300,0,0,0,0,0),
      Food(167512, "","",300,0,0,0,0,0)
    ];
  }

  getInvalidFoodList(){
    return [
      Food(167512, "","",300,0,0,0,0,0),
      Food(167512, "","",300,0,0,0,0,0),
      Food(167512, "","",300,0,0,0,0,0),
      Food(167512, "","","300",0,0,0,0,0),
      Food(167512, "","",-200,0,0,0,0,0)
    ];
  }

  test('check if given timestamp returns valid timespan or catches invalid timestamp', () {
    List<int> day = dataService.getTimestampsByTimestampAndTimespan(TimeSpan.day,getTimestampFromNow());
    expect(31, day.length);
    List<int> week = dataService.getTimestampsByTimestampAndTimespan(TimeSpan.week,getTimestampFromNow());
    expect(7, week.length);
    List<int> month = dataService.getTimestampsByTimestampAndTimespan(TimeSpan.month,getTimestampFromNow());
    expect(31, month.length);
    List<int> invalidTimestamp = dataService.getTimestampsByTimestampAndTimespan(TimeSpan.month,9999999999999);
    expect(0, invalidTimestamp.length);
  });

  test('check if dates are returned correctly from timestamp', () {
    int day = dataService.getDayAsIntFromTimestamp(getTimestampFromNow());
    expect(DateTime.now().day, day);
    int month = dataService.getMonthAsIntFromTimestamp(getTimestampFromNow());
    expect(DateTime.now().month, month);
    int year = dataService.getYearAsIntFromTimestamp(getTimestampFromNow());
    expect(DateTime.now().year, year);
  });

  test('check if date comparison is right', () {
    int today = getTimestampFromNow();
    expect(true,dataService.isDateEqual(today, today));
    int other = getTimeStampForDateTime(DateTime.utc(2010));
    expect(false,dataService.isDateEqual(today, other));
    expect(false,dataService.isDateEqual(9999999999999, today));
    expect(false,dataService.isDateEqual(other, 9999999999999));
    expect(false,dataService.isDateEqual(other, -1));
    expect(false,dataService.isDateEqual(other, 0));
  });

  test('check if calories are summed up correctly for given food list',() {
    expect(1500, dataService.getSumOfCaloriesByFoodList(getFoodListValid()));
    expect(() => dataService.getSumOfCaloriesByFoodList(getInvalidFoodList()),throwsException);
  });

  test('check if format helper are working right',() {
    expect(2,getListOfDistinctElements(getFoodListValid()).length);
    expect(3,getMapOfDistinctElementsWithCounterAndCalories(getFoodListValid()).keys.length);
    expect("Testfood",getToastFoodNameString(getFoodListValid()[0],null));
    expect("TestfoodTestfoodTestfo ...",getToastFoodNameString(getFoodListValid()[1],null));
    Food food = getFoodListValid()[0];
    expect("Testfood 2 x 600 kcal", getFoodListStringByFood(food.name, 2, 600,null));
  });

}
