import 'dart:convert';
import 'dart:io';

import 'package:app_hit_a_wod/src/blocs/box_calendar_page.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/create-benchmark/user_benchmark_create.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/create-benchmark/user_benchmark_line_create.bloc.dart';
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/user_edit_form.bloc.dart';
import 'package:app_hit_a_wod/src/models/bi_training_session.model.dart';
import 'package:app_hit_a_wod/src/models/training_session.model.dart';
import 'package:app_hit_a_wod/src/models/training_workout.model.dart';
import 'package:app_hit_a_wod/src/models/training_workout_line.model.dart';
import 'package:app_hit_a_wod/src/models/training_workout_section.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/providers/auth.provider.dart';
import 'package:app_hit_a_wod/src/providers/user-subscriptions.provider.dart';
import 'package:app_hit_a_wod/src/styles.dart';
import 'package:app_hit_a_wod/src/utils.dart';
import 'package:app_hit_a_wod/src/utils/custom_datepicker/datetimepicker_neu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';

class UserBenchmarkCreatePage extends StatelessWidget {
  Widget build(BuildContext context) {
    ApiProvider _api = Provider.of<ApiProvider>(context);
    final double formWidth = 80;
    final auth = Provider.of<AuthProvider>(context);
    final BITrainingSession ts = ModalRoute.of(context).settings.arguments;
    final UserSubscriptionsProvider us_provider = Provider.of<UserSubscriptionsProvider>(context);
    final UserBenchmarkCreateFormBloc bloc = UserBenchmarkCreateFormBloc(training_session: ts, user: auth.currentUser, api: _api);
    final BoxCalendarPageBloc blocTrainingSessions = BoxCalendarPageBloc(
      context: context, 
      box_id: us_provider.currentActiveSubscription.box.id, 
      day: ts.date_start
    );

    final DashboardBloc dashboardBloc = DashboardBloc(context: context, user_id: auth.currentUser.id, box_id: us_provider.currentActiveSubscription.box.id, subscription_selection_id: us_provider.currentActiveSubscription.us.id);
    final StatsBloc statsBloc = StatsBloc(
      context: context, 
      user_id: auth.currentUser.id,
      box_id: us_provider.currentActiveSubscription.box.id, 
    );

    return neuScaffoldDetail(
      context: context,
      title: Text("Entra tu resultado", style: Theme.of(context).textTheme.subhead.copyWith(fontWeight: FontWeight.w500, fontSize: 18)),
      action: StreamBuilder<String>(
        stream: bloc.statusStream,
        builder: (context, snapshot) {
          return FlatButton(
            child: snapshot.hasData && snapshot.data == "loading" ? 
              CircularProgressIndicator(strokeWidth: 3, backgroundColor: Colors.transparent, valueColor: new AlwaysStoppedAnimation<Color>(colors['primary']),) : 
              Text("Guardar", style: Theme.of(context).textTheme.display1.copyWith(fontWeight: FontWeight.w500)),
            onPressed: () { 
              if (!snapshot.hasData || snapshot.data != "loading") {
                bloc.save(context, blocTrainingSessions, us_provider.currentActiveSubscription.box.id, ts, dashboardBloc , auth.currentUser.id, us_provider.currentActiveSubscription.us.id, statsBloc);
              }
            }
          );
        }
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(20),
        child: Container(
          width: double.infinity,
          child: Column(
            children: <Widget>[
              Text("Workout",style: Theme.of(context).textTheme.subtitle),
              Text("${ts.training_workout.name!=null ? ts.training_workout.name + ', ' : ''}${ts.training_workout.category}",style: Theme.of(context).textTheme.subtitle),
              SizedBox(height: 10.0),
              Text('Sesión: ${DateFormat('dd').format(ts.date_start)} de ${DateFormat('MMMM').format(ts.date_start)} del ${DateFormat('yyyy').format(ts.date_start)}', style: Theme.of(context).textTheme.body1),
              SizedBox(height: 20.0),
              getMiniWorkout(context,ts.training_workout),
              SizedBox(height: 20.0),
              _getWorkout(context, ts.training_workout, bloc, auth.currentUser, ts),
            ],
          )
        )
      )
    );
  }

  _getWorkout(BuildContext context, TrainingWorkout tw, UserBenchmarkCreateFormBloc bloc, User user, BITrainingSession ts) {
    return StreamBuilder<int>(
      stream: bloc.selectedLvlStream,
      builder: (context, snapshot) {
        return neuContainer(
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Row(
                children: <Widget>[
                  Expanded(child: Text("Workout", style: Theme.of(context).textTheme.subtitle2,)),
                  NeumorphicToggle(
                    style: NeumorphicToggleStyle(backgroundColor: neuColor, borderRadius: BorderRadius.circular(8)),
                    width: 210.0,
                    height: 50.0,
                    selectedIndex: snapshot.hasData ? snapshot.data : 0,
                    displayForegroundOnlyIfSelected: true,
                    children: [
                      ToggleElement(
                        background: Center(
                          child: Text('RX', style: Theme.of(context).textTheme.body1)
                        ),
                        foreground: Center(
                          child: shaderContainer(Text('RX', style: Theme.of(context).textTheme.body1.copyWith(fontWeight: FontWeight.w500)), 'letter', primaryColors)
                        )
                      ),
                      ToggleElement(
                        background: Center(
                          child: Text('SC', style: Theme.of(context).textTheme.body1)
                        ),
                        foreground: Center(
                          child: shaderContainer(Text('SC', style: Theme.of(context).textTheme.body1.copyWith(fontWeight: FontWeight.w500)), 'letter', primaryColors)
                        ),
                      ),
                      ToggleElement(
                        background: Center(
                          child: Text('Otro', style: Theme.of(context).textTheme.body1)
                        ),
                        foreground: Center(
                          child: shaderContainer(Text('Otro', style: Theme.of(context).textTheme.body1.copyWith(fontWeight: FontWeight.w500)), 'letter', primaryColors)
                        ),
                      ),
                    ],
                    thumb: Neumorphic(
                      style: neuStyle(),
                    ),
                    onChanged: (value) {
                      bloc.selectLevel(value,user);
                    },
                  )
                ],
              ),
              SizedBox(height: 20.0,),
              bloc.selectedLvlValue==2 ? Text("Si seleccionas 'Otro', podrás introducir tus propios pesos, pero no se tendrán en cuenta para generar la puntuación", style: Theme.of(context).textTheme.subtitle.copyWith(fontSize: 14.0, fontStyle: FontStyle.italic),) : SizedBox(),
              SizedBox(height: 20.0,),
              StreamBuilder<List<UserBenchmarkSectionCreateBloc>>(
                stream: bloc.sectionsStream,
                builder: (context, list) {
                  if(list.hasData) {
                    return Wrap(
                      runSpacing: 20.0,
                      children: list.data.map((sectionBloc) => _generateSection(context,sectionBloc,ts,user,snapshot.data)).toList()
                    );
                  }
                  else return Container();
                }
              )        
            ],
          ),
          width: double.infinity
        );
      }
    );
  }

  Widget _generateSection(BuildContext context, UserBenchmarkSectionCreateBloc bloc, BITrainingSession bits, User user, int levelSelected) {
    TextEditingController roundsController = TextEditingController(text: bloc.roundsValue!=null ? bloc.roundsValue.toString() : null);
    TextEditingController customScoreController = TextEditingController(text: bloc.customScoreValue!=null ? bloc.customScoreValue.toString() : null);
    return neuContainer(
      Column(
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                width: double.infinity,
                child: Row(
                  children: <Widget>[
                    Expanded(child: Text("${bloc.tws.type}", style: Theme.of(context).textTheme.subtitle2.copyWith(fontSize: 16.0),)),
                    bloc.tws.rounds!=null ? 
                      neuChip(
                        Text("${bloc.tws.rounds} rondas", style: Theme.of(context).textTheme.display2,),
                        colors: secondaryShadow
                      ) : bloc.tws.seconds!=null ? neuChip(
                          Text("${bloc.tws.type=='For Time' ? 'Time cap: ' : ''}${[Duration(seconds: bloc.tws.seconds).inHours, Duration(seconds: bloc.tws.seconds).inMinutes, Duration(seconds: bloc.tws.seconds).inSeconds].map((seg) => seg.remainder(60).toString().padLeft(2, '0')).join(':')}", style: Theme.of(context).textTheme.display2,)
                        ) : SizedBox(height: 0.0, width: 0.0,),
                  ],
                ),
              ),
              bloc.tws.seconds!=null && bloc.tws.rounds!=null ? neuChip(
                Text("${bloc.tws.type=='For Time' ? 'Time cap: ' : ''}${[Duration(seconds: bloc.tws.seconds).inHours, Duration(seconds: bloc.tws.seconds).inMinutes, Duration(seconds: bloc.tws.seconds).inSeconds].map((seg) => seg.remainder(60).toString().padLeft(2, '0')).join(':')}", style: Theme.of(context).textTheme.display2,)
              ) : SizedBox(height: 0.0, width: 0.0,),
              SizedBox(height: 20.0,),
              bloc.tws.description!=null && bloc.tws.description.isNotEmpty ? Container(
                width: double.infinity,
                child: Text("${bloc.tws.description}", style: Theme.of(context).textTheme.body1)
              ) : SizedBox(),
              bloc.tws.description!=null && bloc.tws.description.isNotEmpty ? SizedBox(height: 20.0,) : SizedBox(),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  bloc.tws.scoring['time'] ? 
                  Container(
                    child: StreamBuilder<String>(
                      stream: bloc.timeStream,
                      builder: (context, snapshot) {
                        return neuTimeEntry(context,
                          child: Text('${snapshot.data!=null ? snapshot.data : '--:--:--'}'),
                          onConfirm: (date) { bloc.setTime(UtilsHAW.dateToCronoTime(date)); },
                        );
                      }
                    ),
                  ) : SizedBox(),
                  bloc.tws.scoring['time'] && bloc.tws.scoring['rounds'] ? SizedBox(height: 20.0,) : SizedBox(),
                  bloc.tws.scoring['rounds'] ? 
                  StreamBuilder<int>(
                    stream: bloc.roundsStream,
                    builder: (context, snapshot) {
                      return neuInput(
                        Container(
                          width: double.infinity,
                          height: 50,
                          child: TextField(
                            controller: roundsController,
                            keyboardType: TextInputType.number,
                            decoration: InputDecoration(
                              contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
                              border: InputBorder.none,
                              hintText: 'Rondas',
                              errorText: snapshot.error,
                              suffixText: "Rondas",
                              errorStyle: TextStyle(color: colors["seven"])
                            ),
                            onChanged: (val) { bloc.setRounds(int.parse(val)); },
                          )
                        )
                      );
                    }
                  ) : SizedBox(),
                  bloc.tws.scoring['rounds'] && bloc.tws.scoring['completed'] ?  SizedBox(height: 20.0, width: 20.0,) : SizedBox(),
                  bloc.tws.scoring['completed'] ? 
                  StreamBuilder<int>(
                    stream: bloc.completedStream,
                    builder: (context, snapshot) {
                      return Wrap(
                        crossAxisAlignment: WrapCrossAlignment.center,
                        runSpacing: 10.0,
                        spacing: 10.0,
                        children: <Widget>[
                          Container(
                            padding: bloc.tws.scoring['time'] || bloc.tws.scoring['rounds'] || bloc.tws.scoring['completed'] ? EdgeInsets.only(top: 10.0,) : EdgeInsets.all(0.0),
                            child: Text('Has completado esta sección? ', style: Theme.of(context).textTheme.body1,)
                          ),
                          NeumorphicCheckbox(
                            value: snapshot.data!=null && snapshot.data==1 ? true : false,
                            style: neuCheckboxStyle(),
                            onChanged: (value) { bloc.setCompleted(value ? 1 : 0); },
                          )
                        ],
                      );
                    }
                  ) : SizedBox(),
                  bloc.tws.custom_score==1 ?
                  Container(
                    width: double.infinity,
                    padding: EdgeInsets.only( top: bloc.tws.scoring['completed'] || bloc.tws.scoring['rounds'] ? 20.0 : 0.0 ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text("Introduce tu puntuación siguiendo la siguiente explicación", style: Theme.of(context).textTheme.body1.copyWith(fontWeight: FontWeight.w500),),
                        SizedBox(height: 10.0,),
                        Text("${bloc.tws.custom_score_explanation}", style: Theme.of(context).textTheme.body1,),
                        SizedBox(height: 10.0,),
                        StreamBuilder<int>(
                          stream: bloc.customScoreStream,
                          builder: (context, snapshot) {
                            return neuInput(
                              Container(
                                width: double.infinity,
                                height: 50,
                                child: TextField(
                                  controller: customScoreController,
                                  keyboardType: TextInputType.numberWithOptions(decimal:false),
                                  decoration: InputDecoration(
                                    contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
                                    border: InputBorder.none,
                                    hintText: 'Puntuación',
                                    errorText: snapshot.error,
                                    suffixText: "pt",
                                    errorStyle: TextStyle(color: colors["seven"])
                                  ),
                                  onChanged: (val) { bloc.setCustomScore(int.parse(val)); },
                                ),
                              )
                            );
                          }
                        )
                      ],
                    ),
                  ): SizedBox()
                ]
              ),
            ],
          ),
          StreamBuilder<List<UserBenchmarkLineCreateBloc>>(
            stream: bloc.linesStream,
            builder: (context, snapshot) {
              if(snapshot.hasData) {
                return Container(
                  margin: EdgeInsets.only(top: 20.0),
                  child: Wrap(
                    runSpacing: 20.0,
                    children: snapshot.data.map((lineBloc) => _generateExercises(context,lineBloc, bits, user, levelSelected)).toList() 
                  ),
                );
              }
              else return Container();
            }
          )
        ],
      ),
      width: double.infinity
    );
  }

  Widget _generateExercises(BuildContext context, UserBenchmarkLineCreateBloc bloc, BITrainingSession ts, User user, int levelSelected) {
    final options = {
      "seconds": (levelSelected==0) ? bloc.workoutLine.seconds : bloc.workoutLine.seconds_scaled,
      "reps": (levelSelected==0) ? bloc.workoutLine.reps : bloc.workoutLine.reps_scaled,
      "maleVal": (levelSelected==0) ? bloc.workoutLine.maleVal : bloc.workoutLine.maleVal_scaled,
      "femaleVal": (levelSelected==0) ? bloc.workoutLine.femaleVal : bloc.workoutLine.femaleVal_scaled,
      "units": (levelSelected==0) ? bloc.workoutLine.units : bloc.workoutLine.units_scaled,
    };

    /*if (bloc.getUserBenchmark().user_benchmark_sections[indexS].user_benchmark_lines.length-1<indexL) {
      bloc.initializeUB(ts, user);
      UserBenchmark ub = bloc.getUserBenchmark();
      ub.user_benchmark_sections[indexS].user_benchmark_lines.add(new UserBenchmarkLine());
    }*/

    TextEditingController valorController = TextEditingController(text: bloc.valValue!=null ? bloc.valValue.toString() : null);
    TextEditingController repsController = TextEditingController(text: bloc.repsValue!=null ? bloc.repsValue.toString() : null);
    return neuContainer(
      Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Row(
            children: <Widget>[
              Expanded(child: Text("${(levelSelected==0) ? bloc.workoutLine.exercise.name : bloc.workoutLine.exercise_scaled.name}", style: Theme.of(context).textTheme.subtitle.copyWith(fontSize: 14),)),
              options['seconds']!=null ? SizedBox(height: 20.0,) : SizedBox(),
              options['seconds']!=null ? 
                neuChip(
                  Text("${[Duration(seconds: options['seconds']).inHours, Duration(seconds: options['seconds']).inMinutes, Duration(seconds: options['seconds']).inSeconds].map((seg) => seg.remainder(60).toString().padLeft(2, '0')).join(':')}", style: Theme.of(context).textTheme.display2,)
                ) : SizedBox(height: 0.0, width: 0.0,),
            ],
          ),
          SizedBox(height: 10),
          bloc.workoutLine.description!=null && bloc.workoutLine.description.isNotEmpty ? Text("${bloc.workoutLine.description}", style: Theme.of(context).textTheme.body1.copyWith(fontSize: 12, fontStyle: FontStyle.italic),) : SizedBox(),
          SizedBox(height: bloc.workoutLine.description!=null && bloc.workoutLine.description.isNotEmpty ?  10.0 : 0.0,),
          StreamBuilder(
            stream: CombineLatestStream.combine3(bloc.repsStream, bloc.valStream, bloc.unitsStream, (a, b, c) => {"reps": a, "val": b, "units": c}),
            builder: (context, snapshot) {
              if(snapshot.hasData) {

                String units = snapshot.data["units"];
                String val = snapshot.data["val"];
                String reps = snapshot.data["reps"];
                
                if (val!=null || reps!=null) {
                  return Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      val != null ? 
                      neuInput(
                        Container(
                          width: double.infinity,
                          height: 50,
                          child: TextField(
                            controller: valorController,
                            keyboardType: TextInputType.number,
                            enabled: (levelSelected==2 || options['maleVal'].toString().toLowerCase().contains('max') || options['femaleVal'].toString().toLowerCase().contains('max')),
                            decoration: InputDecoration(
                              contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
                              border: InputBorder.none,
                              hintText: 'Valor',
                              errorText: snapshot.error,
                              suffixText: units,
                              errorStyle: TextStyle(color: colors["seven"])
                            ),
                            onChanged: bloc.setVal,
                          )
                        )
                      ) : SizedBox(),
                      val != null ? SizedBox(height: 10.0,) : SizedBox(),
                      reps != null ? 
                      neuInput(
                        Container(
                          width: double.infinity, 
                          height: 50,
                          child: TextField(
                            controller: repsController,
                            keyboardType: TextInputType.number,
                            enabled: (levelSelected==2 || options['reps'].toString().toLowerCase().contains('max')),
                            decoration: InputDecoration(
                              contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
                              border: InputBorder.none,
                              hintText: 'Reps',
                              errorText: snapshot.error,
                              suffixText: "Reps",
                              errorStyle: TextStyle(color: colors["seven"])
                            ),
                            onChanged: bloc.setReps
                          )
                        ),
                      ) : SizedBox(),                      
                    ],
                  );
                } else return Text("Ejercicio no evaluable", style: Theme.of(context).textTheme.body1.copyWith(fontSize: 14.0),);
              }
              else return Container();
            }
          )
        ],
      ),
      width: double.infinity
    );
  }
}