import 'dart:convert';

import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:flutter/services.dart';
import 'api.dart';

class ExerciseTreeApi with Logging {
  final APIClient _client = new APIClient();

  Future<List<ExerciseTree>> getExerciseTree() async {
    final String body = await _client.get("exercise_tree", "");
    Iterable json = jsonDecode(body);
    List<ExerciseTree>? exerciseTrees = json.map((exerciseTree) => ExerciseTree.fromJson(exerciseTree)).toList();

    exerciseTrees = await getExerciseTreeParents(exerciseTrees);

    await Future.forEach(exerciseTrees, (element) async {
      ExerciseTree exerciseTree = element as ExerciseTree;
      exerciseTree.imageUrl = await buildImage(exerciseTree.imageUrl, exerciseTree.treeId);
    });
    exerciseTrees = await getExerciseTreeParents(exerciseTrees);
    log("ExerciseTree downloaded $exerciseTrees");
    Cache().setExerciseTree(exerciseTrees);

    return exerciseTrees;
  }

  Future<String> buildImage(String imageUrl, int treeId) async {
    String assetImage = 'asset/menu/' + imageUrl.substring(7);
    return await rootBundle.load(assetImage).then((value) {
      return assetImage;
    }).catchError((_) {
      String imagePath = assetImage.substring(10);
      String url = Cache.mediaUrl + 'images' + imagePath;
      return url;
    });
  }

  Future<List<ExerciseTree>> getExerciseTreeParents(List<ExerciseTree> exerciseTree) async {
    List<ExerciseTree> copyList = this.copyList(exerciseTree);

    final String body = await _client.get("exercise_tree_parents", "");
    Iterable json = jsonDecode(body);
    final List<ExerciseTreeParents> exerciseTreeParents =
        json.map((exerciseTreeParent) => ExerciseTreeParents.fromJson(exerciseTreeParent)).toList();

    int treeIndex = 0;
    copyList.forEach((element) async {
      int index = 0;
      exerciseTreeParents.forEach((parent) {
        if (parent.exerciseTreeChildId == element.treeId) {
          if (index > 0) {
            ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
            newElement.sort = parent.sort;
            exerciseTree.add(newElement);
          } else {
            element.parentId = parent.exerciseTreeParentId;
            element.sort = parent.sort;
            exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId;
          }
          index++;
        }
      });
      treeIndex++;
    });
    return exerciseTree;
  }

  List<ExerciseTree> copyList(List<ExerciseTree> tree) {
    final List<ExerciseTree> copyList = [];
    tree.forEach((element) {
      final ExerciseTree copy = element.copy(-1);
      copyList.add(copy);
    });

    return copyList;
  }
}
