import 'package:app_hit_a_wod/src/blocs/create-benchmark/user_benchmark_section_create.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/dashboard.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/stats.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/validators.dart';
import 'package:app_hit_a_wod/src/models/bi_training_session.model.dart';
import 'package:app_hit_a_wod/src/models/training_workout.model.dart';
import 'package:app_hit_a_wod/src/models/user.model.dart';
import 'package:app_hit_a_wod/src/models/user_benchmark.model.dart';
import 'package:app_hit_a_wod/src/models/user_benchmark_line.model.dart';
import 'package:app_hit_a_wod/src/models/user_benchmark_section.model.dart';
import 'package:app_hit_a_wod/src/providers/api.provider.dart';
import 'package:app_hit_a_wod/src/utils.dart';
import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';

import '../box_calendar_page.bloc.dart';

class UserBenchmarkCreateFormBloc with Validators {

  ApiProvider _api;

  UserBenchmark _ub;
  UserBenchmark get ub => _ub;

  //Selected Lvl
  BehaviorSubject<int> _selectedLvlSubject = new BehaviorSubject();
  Stream<int> get selectedLvlStream => _selectedLvlSubject.stream;
  int get selectedLvlValue => _selectedLvlSubject.value;
  Function(int) get _selectedLvlSet => _selectedLvlSubject.sink.add;

  //seccions
  BehaviorSubject<List<UserBenchmarkSectionCreateBloc>> _sectionsSubject = new BehaviorSubject();
  Stream<List<UserBenchmarkSectionCreateBloc>> get sectionsStream => _sectionsSubject.stream;

  //creating
  BehaviorSubject<String> _statusSubject = new BehaviorSubject(); //"init", "loading", "done"
  Stream<String> get statusStream => _statusSubject.stream;

  static UserBenchmarkCreateFormBloc _instancia;
  factory UserBenchmarkCreateFormBloc({BITrainingSession training_session, User user, ApiProvider api}) {
    if(_instancia==null || training_session.id!=_instancia._ub.training_session_id) {
      _instancia = UserBenchmarkCreateFormBloc._internal(training_session, user, api);
    }
    return _instancia;
  }
  UserBenchmarkCreateFormBloc._internal(BITrainingSession ts, User user, ApiProvider this._api) {
    this._selectedLvlSubject.sink.add(0); // 0 = RX, 1 = SC, 2 = CUSTOM
    initializeUB(ts, user);
    selectLevel(0, user);
  }

  UserBenchmark initializeUB(BITrainingSession ts, User user) {
    TrainingWorkout tw = ts.training_workout;
    UserBenchmark ub = new UserBenchmark();
    ub.user_id = user.id;
    ub.training_session_id = ts.id;
    ub.training_workout_id = tw.id;
    List<UserBenchmarkSectionCreateBloc> sectionsBloc = [];
    tw.training_workout_sections.forEach((tws) {
      UserBenchmarkSection ubs = new UserBenchmarkSection();
      ubs.training_workout_section_id = tws.id;
      ubs.time = tws.seconds!=null ? UtilsHAW.dateToCronoTime(new DateTime.fromMicrosecondsSinceEpoch(tws.seconds*1000000)) : null;
      ubs.user_benchmark_lines = [];
      tws.lines.forEach((twl) {
        UserBenchmarkLine ubl = new UserBenchmarkLine();
        ubl.training_workout_line_id = twl.id;
        ubs.user_benchmark_lines.add(ubl);
      });
      _ub = ub;
      sectionsBloc.add(UserBenchmarkSectionCreateBloc(ubs, tws));
    });

    _sectionsSubject.sink.add(sectionsBloc);
  } 

  selectLevel(int lvl, User user) {
    this._selectedLvlSet(lvl);
    this._sectionsSubject.value.forEach((sectionBloc) {
      sectionBloc.setMode(lvl, user.gender);
    });
  }

  save(BuildContext context, BoxCalendarPageBloc blocTrainingSessions, int box_id, BITrainingSession ts, DashboardBloc dashboardBloc, int user_id, int subscription_selection_id, StatsBloc statsBloc) async {
    this._statusSubject.sink.add("loading");
    UserBenchmark ub = this._getBenchmark();
    this._api.postUserBenchmark(ub).then((value) {
      blocTrainingSessions.refreshTrainingSessions(box_id, ts.date_start);
      dashboardBloc.refreshInitPage(user_id, box_id, subscription_selection_id);
      statsBloc.refreshTrainingSessions(user_id, box_id);
      this._statusSubject.sink.add("done");
      Navigator.pop(context);
      Navigator.pushNamed(context, 'user-benchmark-detail', arguments: {'user-benchmark': value, 'training-workout': ts.training_workout});
    }).catchError((err) {
      this._statusSubject.sink.add("init");
    });
  }

  UserBenchmark _getBenchmark() {
    _ub.level = selectedLvlValue==0 ? 'RX' : (selectedLvlValue==1 ? 'SC' : 'Otro');
    _ub.user_benchmark_sections = _sectionsSubject.value.map((sectionBloc) => sectionBloc.getSection()).toList();
    return _ub;
  }
}