import 'dart:collection';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:flutter/material.dart';

class Antagonist {
  static String chest = "Chest";
  static int chestNr = 1;
  static String biceps = "Biceps";
  static int bicepsNr = 2;
  static String triceps = "Triceps";
  static int tricepsNr =3;
  static String back = "Back";
  static int backNr = 4;
  static String shoulder = "Shoulders";
  static int shoulderNr = 5;
  static String core = "Core";
  static int coreNr = 6;
  static String thigh = "Thigh";
  static int thighNr = 7;
  static String calf = "Calf";
  static int calfNr = 8;
}

class MenuTreeRepository {
  final LinkedHashMap tree = LinkedHashMap<String, WorkoutTree>();
  SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
  bool isEnglish;

  final Map<String, int> _antagonist = {
    Antagonist.chest: Antagonist.chestNr,
    Antagonist.biceps: Antagonist.bicepsNr,
    Antagonist.triceps: Antagonist.tricepsNr,
    Antagonist.back: Antagonist.backNr,
    Antagonist.shoulder: Antagonist.shoulderNr,
    Antagonist.core: Antagonist.coreNr,
    Antagonist.thigh: Antagonist.thighNr,
    Antagonist.calf: Antagonist.calfNr
  };

  Future<void> createTree() async {
    final AppLanguage appLanguage = AppLanguage();
    isEnglish = appLanguage.appLocal == Locale('en');
    print("** Start creating tree on lang: " + appLanguage.appLocal.toString());

    List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
    if ( exerciseTree == null || exerciseTree.length == 0) {
      await ExerciseTreeApi().getExerciseTree();
    }

    exerciseTree.forEach( (treeItem) async {
      String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
      String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7);
      bool is1RM = treeItem.name == 'One Rep Max' ? true : false;
      if ( is1RM == false && treeItem.parentId != 0) {
        is1RM = isParent1RM(treeItem.parentId);
      }
      this.tree[treeItem.name] = WorkoutTree(
        treeItem.treeId,
        treeItem.parentId,
        treeName,
        assetImage, Colors.white,
        24,
        false,
        0,
        null,
        false,
        is1RM,
        treeItem.name,
      );
    });

    List<ExerciseType> exerciseTypes = Cache().getExerciseTypes();
    if ( exerciseTypes == null || exerciseTypes.length == 0) {
      await ExerciseTypeApi().getExerciseTypes();
    }

    exerciseTypes.forEach( (exerciseType) {
      String exerciseTypeName = isEnglish ?
        exerciseType.name : exerciseType.nameTranslation;
      String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
      bool is1RM = this.isParent1RM(exerciseType.treeId);
      exerciseType.is1RM = is1RM;
      this.tree[exerciseType.name] = WorkoutTree(
        exerciseType.exerciseTypeId,
        exerciseType.treeId,
        exerciseTypeName,
        assetImage,
        Colors.white,
        16,
        true,
        exerciseType.exerciseTypeId,
        exerciseType,
        exerciseType.base,
        is1RM,
        exerciseType.name
      );
    });

    Cache().setWorkoutTree(tree);
    ExerciseRepository exerciseRepository = ExerciseRepository();
    exerciseRepository.getBaseExerciseFinishedPercent();
  }

  bool isParent1RM(int treeId) {
    bool isTreeItem1RM = false;

    this.tree.forEach((key, value) {
      WorkoutTree treeItem = value as WorkoutTree;
      if ( treeItem.id == treeId ) {
        isTreeItem1RM = treeItem.is1RM;
        print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
      }

    });

    return isTreeItem1RM;
  }

  LinkedHashMap getBranch(int parent) {
    LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
    tree.forEach((key, value) {
      WorkoutTree workoutTree = value as WorkoutTree;
      if ( parent == workoutTree.parent) {
        branch[key] = value;
      }
    });
    return branch;
  }

  List<WorkoutTree> getBranchList(int parent) {
    List branch = List<WorkoutTree>();
    tree.forEach((key, value) {
      WorkoutTree workoutTree = value as WorkoutTree;
      if ( parent == workoutTree.parent) {
        branch.add(workoutTree);
      }
    });
    return branch;
  }

  void sortByMuscleType() {
    sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
    tree.forEach((key, value) {
      WorkoutTree workoutTree = value as WorkoutTree;
      //print("treeitem: " + workoutTree.toJson().toString());
      /*if ( workoutTree.exerciseType != null) {
        print("treeItem exerciseTye " + workoutTree.exerciseType.toJson().toString());
      } else {
        print("treeItem exerciseType null " + workoutTree.toJson().toString());
      }*/
      if ( workoutTree.nameEnglish != 'One Rep Max' && workoutTree.is1RM && workoutTree.exerciseTypeId == 0) {
        String treeName = _antagonist[workoutTree.nameEnglish].toString() + ". " + workoutTree.name;
        sortedTree[treeName] = this.getBranchList(workoutTree.id);
      }
    });

    return;
  }
}