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/training_workout_section.model.dart';
import 'package:app_hit_a_wod/src/models/user.model.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:app_hit_a_wod/src/utils/custom_popup/popup.dart';
import 'package:app_hit_a_wod/src/utils/custom_popup/popup_content.dart';
import 'package:app_hit_a_wod/src/utils/custom_training_session_action_button.dart/training_session_action_button.dart';
import 'package:app_hit_a_wod/src/utils/fontello/my_flutter_app_icons.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:intl/intl.dart';
import 'package:skeleton_text/skeleton_text.dart';

const Color neuColor = Color.fromRGBO(242, 243, 246, 1);
const Color neuColorPressed = Color.fromRGBO(255, 255, 255, 1);
const Color neuShadowDarkColor = Color.fromRGBO(36, 65, 93, 0.3);
double neuDepth = 5;
double neuDepthPressed = -5;
double neuButtonRounded = 5;
double neuRounded = 16;
double neuRoundedChip = 20;
double neuRoundedButton = 30;
const List<Color> primaryShadow = const [const Color.fromRGBO(141, 39, 144, 1), const Color.fromRGBO(56, 52, 147, 1)];
const List<Color> secondaryShadow = const [const Color(0xFF383493), const Color(0xFF4741BA)]; //es el gradient lila
const List<Color> primaryColors = const [const Color(0xFF8B278F), const Color(0xFFB131B5)]; //es el gradient rosa
const List<Color> neuInverseColors = const [const Color(0xFFE9EAEF), const Color(0xFFF8F8FC)];
const List<Color> successColors = const [const Color.fromRGBO(70, 118, 139, 1), const Color.fromRGBO(70, 118, 139, 1)];
const List<Color> wrongColors = const [const Color.fromRGBO(198, 46, 101, 1), const Color.fromRGBO(198, 46, 101, 1)];

shaderContainer(Widget w, String type, [List<Color> c = primaryShadow]) {
  if (type == 'out') {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: c,
          )
        ),
        child: w
      )
    );
  } else if (type == 'letter') {
    return Center(
      child: ShaderMask(
        blendMode: BlendMode.srcATop,
        shaderCallback: (Rect bounds) {
          return LinearGradient(
            colors: c,
            tileMode: TileMode.mirror,
          ).createShader(bounds);
        },
        child: w
      )
    );
  } else {
    return Center(
      child: ShaderMask(
        blendMode: BlendMode.srcATop,
        shaderCallback: (Rect bounds) {
          return LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,            
            colors: c,
          ).createShader(Offset.zero & bounds.size);
        },
        child: w
      )
    );
  }
}

/* ESTILOS */
neuStyle([Color color = neuColor]) {
  return NeumorphicStyle(
    color: color,
    depth: neuDepth,
    shadowDarkColor: neuShadowDarkColor,
  );
}

neuButtonStyle() {
  return NeumorphicStyle(
    color: Colors.transparent,
    depth: neuDepth,
    shadowDarkColor: neuShadowDarkColor,
  );
}

Widget neuButton(Widget w, { BorderRadius borderRadius, List<Color> colors = neuInverseColors, double width, double height, EdgeInsets padding }) {
  if(borderRadius==null) borderRadius = BorderRadius.circular(neuButtonRounded);

  return Container(
    decoration: BoxDecoration(
      gradient: LinearGradient(
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
        stops: [-0.2, 1.2],
        colors: colors
      ),
      borderRadius: borderRadius,
    ),
    child: w,
    width: width,
    height: height,
    padding: padding
  );
}

Widget neuDatePicker(Widget w, { BorderRadius borderRadius, List<Color> colors = neuInverseColors }) {
  return Neumorphic(
    style: neuStylePressed(),
    boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(neuRounded)),
    child: Container(
      child:w
    )
  );
  /* return Container(
    decoration: BoxDecoration(
      gradient: LinearGradient(
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
        stops: [-0.2, 1.2],
        colors: colors
      ),
      borderRadius: borderRadius,
    ),
    child: w
  );  */
}

neuButtonCircular(Widget w, { List<Color> colors = neuInverseColors }) {
  return Container(
    decoration: BoxDecoration(
      gradient: LinearGradient(
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
        stops: [-0.2, 1.2],
        colors: colors
      ),
      shape: BoxShape.circle
    ),
    child: w
  );
}

neuBoxShape({ double borderRadius }) {
  if(borderRadius==null) borderRadius = neuButtonRounded;
  return NeumorphicBoxShape.roundRect(BorderRadius.circular(borderRadius));
}

neuStylePressed() {
  return NeumorphicStyle(
    color: Colors.transparent,
    depth: neuDepthPressed,
    shadowDarkColor: neuShadowDarkColor
  );
}

neuStyleButtonPagination(bool enabled) {
  if (enabled) return neuStyle();
  else return neuStylePressed();
}

neuSwitchStyle([Color color = neuColor]) {
  return NeumorphicSwitchStyle(
    inactiveTrackColor: color,
    inactiveThumbColor: color,
    activeTrackColor: colors['primary'],
    activeThumbColor: Color.fromRGBO(242, 243, 246, 1)
  );
}

neuCheckboxStyle() {
  return NeumorphicCheckboxStyle(
    selectedColor: colors['primary'],
    
  );
}

/* COMPONENTS */

neuChip(Widget w, { List<Color> colors = primaryColors, EdgeInsets padding = const EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0) }) {
  return Container(
    decoration: BoxDecoration(
      gradient: LinearGradient(
        colors: colors,
      ),
      borderRadius: BorderRadius.circular(neuRoundedChip),
    ),
    child: Neumorphic(
      style: NeumorphicStyle(
        color: Colors.transparent,
        depth: neuDepth,
        shadowDarkColor: neuShadowDarkColor,
      ),
      padding: padding,
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(neuRoundedChip)),
      child: w,
    ),
  );
}

Widget neuContainer(Widget w, {Color color = neuColor, EdgeInsets padding = const EdgeInsets.all(20), EdgeInsets margin = const EdgeInsets.all(0), BorderRadius borderRadius, NeumorphicBoxShape shape, double width, double height }) {
  if(borderRadius==null) borderRadius = BorderRadius.circular(neuRounded);
  if(shape==null) shape = NeumorphicBoxShape.roundRect(borderRadius);

  return Container(
    width: width,
    height: height,
    margin: margin,
    decoration: BoxDecoration(
      gradient: neuGradientInverse,
      borderRadius: borderRadius,
    ),
    child: Neumorphic(
      padding: padding,
      style: NeumorphicStyle(
        color: Colors.transparent,
        shadowDarkColor: neuShadowDarkColor,
      ),
      boxShape: shape,
      child: w,
    ),
  );
}

neuSkeletonCard(double height, double width) {
  return neuContainer(
    SkeletonAnimation(
      gradientColor: neuColor,
      child: Container(
        height: height,
        width: width,
      ),
    ),
    padding: EdgeInsets.all(0.0)
  );
}

Widget neuSkeletonCircle(double height, double width) {
  return Container(
    decoration: BoxDecoration(
      gradient: neuGradientInverse,
      shape: BoxShape.circle
    ),
    child: Neumorphic(
      style: NeumorphicStyle(
        color: Colors.transparent,
        shadowDarkColor: neuShadowDarkColor,
      ),
      boxShape: NeumorphicBoxShape.circle(),
      child: SkeletonAnimation(
        gradientColor: neuColor,
        child: Container(
          height: height,
          width: width,
          decoration: BoxDecoration(
            shape: BoxShape.circle
          ),
        ),
      ),
    ),
  );
}

Widget neuInput(Widget w, {padding = const EdgeInsets.only(left: 20), margin = const EdgeInsets.all(0)}) {
  return Neumorphic(
    margin: margin,
    style: neuStylePressed(),
    boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(neuRounded)),
    child: Container(
      padding: padding,
      color: neuColor,
      child:w
    )
  );
}

generateGradient(int r, int g, int b) {
  return [Color.fromRGBO(r, g, b, 1),Color.fromRGBO(r+20, g+20, b+20, 1)];
}

const Map<String,Color> colors = {
  'primary': const Color.fromRGBO(141, 39, 144, 1),
  'secondary': const Color.fromRGBO(44, 56, 144, 1),
  'three': const Color.fromRGBO(155, 126, 222, 1),
  'four': const Color.fromRGBO(42, 68, 111, 1),
  'five': const Color.fromRGBO(114, 128, 172, 1),
  'six': const Color.fromRGBO(70, 118, 139, 1),
  'seven': const Color.fromRGBO(198, 46, 101, 1),
  'white': const Color(0xFFF8F8FC),
  'text': const Color(0xFF575F6B),
};

Map<String,List<Color>> colors_list = {
  'primary': generateGradient(141, 39, 144),
  'secondary': generateGradient(44, 56, 144),
  'three': generateGradient(155, 126, 222),
  'four': generateGradient(42, 68, 111),
  'five': generateGradient(114, 128, 172),
  'six': generateGradient(70, 118, 139),
  'seven': generateGradient(198, 46, 101),
  'white': [Color(0xFFF8F8FC),Color(0xFFF8F8FC)],
  'text': [Color(0xFF575F6B),Color(0xFF575F6B)],
};

Map<String,String> colors_category = {
  "For Time": "primary",
  "Rest": "secondary",
  "Tabata": "three",
  "For max total load": "four",
  "For Load": "five",
  "EMOM": "six",
  "Death By": "seven",
  "Chipper": "three", 
  "AMRAP": "seven",
  "AMRAP For As Long As Possible": "seven"
};

Map<String,String> colors_type = {
  "wod": "primary",
  "open": "secondary",
  "olympics": "three",
  "power": "four",
  "endurance": "five",
  "gymnastics": "six",
  "unset": "seven",
  "basics": "three", 
  "mobility": "four",
  "kids": "five",
  "advance": "six",
  "special": "secondary",
  "megawod": "primary",
  "on_ramp": "three"
};

Map<String,String> colors_level = {
  "1": "six",
  "2": "four",
  "3": "seven"
};

Gradient neuGradient = LinearGradient(
  begin: Alignment.topLeft,
  end: Alignment.bottomRight,
  stops: [-0.2, 1.2],
  colors: [
    Color(0xFFF8F8FC),
    Color(0xFFE1E2E8)
  ]
);

Gradient neuGradientInverse = LinearGradient(
  begin: Alignment.topLeft,
  end: Alignment.bottomRight,
  stops: [-0.2, 1.2],
  colors: [
    Color(0xFFE1E2E8),
    Color(0xFFF8F8FC)
  ]
);

Gradient neuGradientMini = LinearGradient(
  begin: Alignment.topLeft,
  end: Alignment.bottomRight,
  stops: [0, 0.5],
  colors: [
    Color(0xFFF8F8FC),
    Color(0xFFE9EAEF)
  ]
);

Gradient neuGradientInverseMini = LinearGradient(
  begin: Alignment.topLeft,
  end: Alignment.bottomRight,
  stops: [-0.2, 1.2],
  colors: neuInverseColors
);

neuDialog({@required Widget child, @required BuildContext context, EdgeInsets padding = const EdgeInsets.all(20), double margin = 10}) => showDialog(
  context: context,
  builder: (BuildContext context) {
    return Dialog(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), //this right here
      child: SingleChildScrollView(
        child: Container(
          width: MediaQuery.of(context).size.width - (margin*2),
          decoration: BoxDecoration(
            gradient: neuGradientInverse,
            borderRadius: BorderRadius.circular(neuRounded),
          ),
          padding: padding,
          child: child
        ),
      )
    );
  }
);

showPopup(BuildContext context, Widget widget, {String animationType = 'center', String position = 'center', double height, BuildContext popupContext}) {
  double h = MediaQuery.of(context).size.height;
  Navigator.push(
    context,
    PopupLayout(
      top: (position!='center') ? ( (position=='top') ? 20 : (h-height-40) ) : (h-height-40)/2,
      left: 20,
      right: 20,
      bottom: (position!='center') ? ( (position=='top') ? (h-height-40) : 20 ) : (h-height-40)/2,
      animationType: animationType,
      position: position,
      height: height,
      child: PopupContent(
        content: Scaffold(
          resizeToAvoidBottomPadding: false,
          backgroundColor: Colors.transparent,
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            elevation: 0,
            leading: new Builder(builder: (context) {
              return IconButton(
                icon: Icon(Icons.arrow_back, color: Color(0xFF575F6B)),
                onPressed: () {
                  try {
                    Navigator.pop(context); //close the popup
                  } catch (e) {}
                },
              );
            }),
          ),
          body: SingleChildScrollView(
            child: widget,
          )
        ),
      ),
    ),
  );
}

/* 

return SingleChildScrollView(
  padding: EdgeInsets.all(20),
  child: Container(
    color: Colors.transparent,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[],
    )
  ),
);

 */

TextStyle neuFormLabelStyle() {
  return TextStyle(
    color: colors["text"],
    fontWeight: FontWeight.w500,
    fontSize: 16
  );
}

neuScaffoldDetail({@required BuildContext context, @required Widget body, @required Widget action, @required Widget title, IconButton leading = null}) {
  return GestureDetector(
    onTap: () {
      FocusScopeNode currentFocus = FocusScope.of(context);
      if (!currentFocus.hasPrimaryFocus) {
        currentFocus.unfocus();
      }
    },
    child: Container(
      decoration: BoxDecoration(
        gradient: neuGradient
      ),
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          leading: (leading==null) ?
            IconButton(
              icon: Icon(Icons.arrow_back, color: Colors.black),
              onPressed: () => Navigator.of(context).pop(),
            )
            :
            leading,
          iconTheme: IconThemeData(color: colors["text"]),
          backgroundColor: Color(0xFFEFF0F3),
          elevation: 5,
          title: title,
          brightness: Brightness.light,
          actions: [action]
        ),
        body: body
      )
    )
  );
}

Widget neuProfilePhoto(BuildContext context, User user,{EdgeInsets margin = const EdgeInsets.all(0.0), double sizeInside = 40, double sizeOutside = 50, int user_id = null, bool showDialog = true}) {
  return InkWell(
    child: Container(
      margin: margin,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        gradient: (user_id==null) ? neuGradientInverseMini : (user_id==user.id) ? LinearGradient(colors: primaryShadow) : neuGradientInverseMini,
      ),
      alignment: Alignment.center,
      child: Container(
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          image: DecorationImage(
            fit: BoxFit.cover,
            image: CachedNetworkImageProvider(user.url_profile_photo),
          ),
          boxShadow: [BoxShadow(
            color: neuShadowDarkColor,
            blurRadius: 10,
            spreadRadius: -2,
            offset: Offset(3.0, 3.0, )
          )]
        ),
        width: sizeInside,
        height: sizeInside
      ),
      width: sizeOutside,
      height: sizeOutside
    ),
    onTap: () {
      if (showDialog) {
        neuDialog(
          context: context,
          child: Container(
            child: Row(
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    image: DecorationImage(
                      fit: BoxFit.cover,
                      image: CachedNetworkImageProvider(user.url_profile_photo),
                    ),
                    boxShadow: [BoxShadow(
                      color: neuShadowDarkColor,
                      blurRadius: 10,
                      spreadRadius: -2,
                      offset: Offset(3.0, 3.0, )
                    )]
                  ),
                  width: 100,
                  height: 100
                ),
                SizedBox(width: 20.0,),
                Expanded(
                  child: Container(
                    height: 110,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Expanded(child: Text("Nombre", style: Theme.of(context).textTheme.subtitle.copyWith(fontSize: 14.0), overflow: TextOverflow.ellipsis,)),
                        SizedBox(height: 10.0,),
                        Expanded(child: Text("${user.name} ${user.surnames}", style: Theme.of(context).textTheme.display1, overflow: TextOverflow.ellipsis)),
                        SizedBox(height: 25.0,),
                        Expanded(child: Text("Miembro desde", style: Theme.of(context).textTheme.subtitle.copyWith(fontSize: 14.0), overflow: TextOverflow.ellipsis)),
                        SizedBox(height: 10.0,),
                        Expanded(child: Text("${DateFormat('dd/MM/yyy').format(user.created_at)}", style: Theme.of(context).textTheme.display1, overflow: TextOverflow.ellipsis))
                      ],
                    ),
                  ),
                )
                
              ],
            ),
          )
        );
      }
    },
  );
}

Widget getMiniWorkout(BuildContext context, TrainingWorkout tw) {
  return neuContainer(
    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Container(
          width: double.infinity,
          child: Wrap(
            spacing: 10.0,
            runSpacing: 10.0,
            alignment: WrapAlignment.spaceBetween,
            children: <Widget>[
              tw.category!=null ? neuChip(
                Text('${tw.category}',style: TextStyle(color: Colors.white),),
                /* colors_list[colors_type[ts.training_type.slug]] */
              ) : SizedBox(),
              neuButton(
                NeumorphicButton(
                  boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
                  padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
                  style: NeumorphicStyle(
                    color: Colors.transparent,
                    depth: neuDepth,
                  ),
                  child: Wrap(
                    spacing: 5,
                    runSpacing: 5,
                    alignment: WrapAlignment.center,
                    crossAxisAlignment: WrapCrossAlignment.center,
                    children: <Widget>[
                      Text('Ver Workout', style: TextStyle(color: colors['primary']),),
                      Icon(MyFlutterApp.right_arrow, color: colors['primary'],size: 15.0)
                    ],
                  ),
                  onClick: () {
                    Navigator.pushNamed(context, 'training-workout-detail', arguments: tw);
                  }
                ),
                colors: generateGradient(235, 235, 235),
                borderRadius: BorderRadius.circular(30),
              )
            ],
          ),
        ),
        SizedBox(height: 20.0),
        Text('${tw.name!=null ? tw.name : ''}', style: Theme.of(context).textTheme.subtitle),
        SizedBox(height: tw.name!=null ? 10.0 : 0),
        _generateDetailMiniWorkout(context,tw)        
      ],
    ),
    width: double.infinity
  );
}

_generateDetailMiniWorkout(BuildContext context, TrainingWorkout tw) {
  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: new List.generate(tw.training_workout_sections.length, (i)=>_generateDetailSectionMiniWorkout(context,tw.training_workout_sections[i]))
  );
}

_generateDetailSectionMiniWorkout(BuildContext context, TrainingWorkoutSection section) {
  String detail = '';
  section.lines.forEach((line) {
    detail = detail + line.exercise.name + ((line.id != section.lines[section.lines.length-1].id) ? ', ' : '');
  });
  detail = detail + '.';
  return Row(
    children: <Widget>[
      Text('${section.type} ',style: Theme.of(context).textTheme.display1,),
      Flexible(
        fit: FlexFit.loose,
        child: Text(
          "${detail}",
          softWrap: false,
          overflow: TextOverflow.ellipsis,
          style: Theme.of(context).textTheme.body1,
        ),
      )
    ],
  );
}

trainingSessionActionButton(BuildContext context, BITrainingSession ts, User user) {
  /* 
    notify -> se apunta para ser notificado cuando haya sitio
    join -> aka se apunta
    joined -> ya apuntado
    leave -> se desapunta
    now -> la clase se esta dando ahora
    future -> se dara en un futuro y aun (o directamente) no te puedes apuntar
    benchmark -> es del pasado, se ha apuntado y ha entrado resultados
    done -> clase hecha
    past -> ya se ha dado la clase y no se ha apuntado
    disabled -> condicion no contemplada, simplemente disabled 
  */
  return neuTrainingSessionActionButton(
    ts: ts,
    // onClicked: (newTs){print("Click");},
    user: user,
  );
}

Widget neuTimeEntry(BuildContext context, { Function(DateTime) onConfirm, Function() onCancel, child: const Text('Entra aqui'), double width: 130}) {
  return Container(
    width: width,
    child: neuInput(
      FlatButton(
        onPressed: () {
          DatePicker.showNeuTimePicker(
            context, showTitleActions: true,
            theme: DatePickerTheme(doneStyle: TextStyle(color: colors['primary'])),
            onChanged: (date) {
              /* print(UtilsHAW.dateToCronoTime(date));
              print('change $date in time zone ' + date.timeZoneOffset.inHours.toString()); */
            },
            onCancel: onCancel,
            onConfirm: onConfirm,
            currentTime: DateTime.parse('2020-01-01 00:00:00')
          );
        },
        child: child,
      ),
      padding: EdgeInsets.all(0)
    ),
  );
}