import 'dart:collection';
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:workouttest_util/repository/exercise_type_repository.dart';

import 'package:workouttest_util/model/customer_training_plan_details.dart';
import 'package:workouttest_util/util/logging.dart';

enum CustomerTrainingPlanType { custom, template, none }

extension CustomerTrainingPlanTypeExt on CustomerTrainingPlanType {
  String toStr() => toString().split(".").last;
  bool equalsTo(CustomerTrainingPlanType type) => toString() == type.toString();
  bool equalsStringTo(String type) => toStr() == type;
}

class CustomerTrainingPlan with Logging {
  int? customerTrainingPlanId;
  int? customerId;
  int? trainingPlanId;
  DateTime? dateAdd;
  bool? active;
  String? status;

  String? name;

  CustomerTrainingPlanType type = CustomerTrainingPlanType.none;

  CustomerTrainingPlan();

  List<CustomerTrainingPlanDetails> details = [];

  HashMap<String, List<CustomerTrainingPlanDetails>> days = HashMap();

  CustomerTrainingPlan.fromJson(Map json) {
    customerTrainingPlanId = json['customerTrainingPlanId'];
    customerId = json['customerId'];
    trainingPlanId = json['trainingPlanId'];
    dateAdd = DateTime.parse(json['dateAdd']);
    active = json['active'];
    status = json['status'];
    name = json['name'];
  }

  CustomerTrainingPlan.fromJsonWithDetails(Map json) {
    customerTrainingPlanId = json['customerTrainingPlanId'];
    customerId = json['customerId'];
    trainingPlanId = json['trainingPlanId'];
    dateAdd = json['dateAdd'] != null ? DateTime.parse(json['dateAdd']) : DateTime.now();
    active = json['active'];
    status = json['status'];
    name = json['name'];

    try {
      final String details = json['details'];
      String jsonDetails = details.replaceAllMapped(RegExp(r'([a-zA-Z]+)\:'), (Match m) => "\"${m[1]}\":");
      jsonDetails = jsonDetails.replaceAllMapped(RegExp(r'\: ([a-zA-Z /]+)'), (Match m) => ":\"${m[1]}\"");

      jsonDetails =
          jsonDetails.replaceAllMapped(RegExp(r'([0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})'), (Match m) => "\"${m[0]}\"");

      log("detail: $jsonDetails");

      Iterable iterable = jsonDecode(jsonDetails);
      this.details = iterable.map((detail) => CustomerTrainingPlanDetails.fromJsonWithExerciseList(detail)).toList();
      for (var detail in this.details) {
        detail.alternatives = ExerciseTypeRepository.getExerciseTypeAlternatives(detail.exerciseTypeId);
      }
    } on Exception catch (e) {
      log("JsonDecode error $e");
    }
  }

  Map<String, dynamic> toJson() => {
        "customerTrainingPlanId": customerTrainingPlanId,
        "customerId": customerId,
        "trainingPlanId": trainingPlanId,
        "dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(dateAdd!),
        "name": name,
        "active": active,
        "status": status
      };

  Map<String, dynamic> toJsonWithDetails() => {
        "customerTrainingPlanId": customerTrainingPlanId,
        "customerId": customerId,
        "trainingPlanId": trainingPlanId,
        "dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(dateAdd!).toString(),
        "name": name,
        "active": active,
        "status": status,
        'details': details.isEmpty ? [].toString() : details.map((detail) => detail.toJsonWithExercises()).toList().toString(),
      };

  @override
  String toString() => toJson().toString();
}