import 'package:app_hit_a_wod/src/blocs/user_edit_form.bloc.dart';
import 'package:app_hit_a_wod/src/blocs/user_page.bloc.dart';
import 'package:app_hit_a_wod/src/models/subscription_selection.model.dart';
import 'package:app_hit_a_wod/src/models/user.model.dart';
import 'package:app_hit_a_wod/src/models/user_assistence.model.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/utils.dart';
import 'package:app_hit_a_wod/src/utils/fontello/my_flutter_app_icons.dart';
import 'package:app_hit_a_wod/src/utils/indicator.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../styles.dart';

class UserPage extends StatelessWidget {
  UserPage({Key key}) : super(key: key);

  int _month = 2;
  final _now = DateTime.now();

  @override
  Widget build(BuildContext context) {
    //inicialitzem data
    final AuthProvider auth = Provider.of<AuthProvider>(context);
    final UserSubscriptionsProvider us_provider = Provider.of<UserSubscriptionsProvider>(context);
    final UserPageBloc bloc = UserPageBloc(
      context: context, 
      box_id: us_provider.currentActiveSubscription!=null ? us_provider.currentActiveSubscription.box.id : null, 
      user_id: auth.currentUser.id, 
      params: {"start_date": DateTime(_now.year, _now.month-_month, _now.day), "end_date": _now}
    );

    return RefreshIndicator(
      onRefresh: () async {
        await auth.refreshToken();
        await bloc.refreshAssistence(us_provider.currentActiveSubscription!=null ? us_provider.currentActiveSubscription.box.id : null, auth.currentUser.id, params: {"start_date": DateTime(_now.year, _now.month-2, _now.day), "end_date": _now});
        return;
      },
      color: colors["primary"],
      displacement: 1,
      child: SingleChildScrollView(
        physics: AlwaysScrollableScrollPhysics(),
        padding: EdgeInsets.all(20),
        child: StreamBuilder(
          stream: CombineLatestStream.combine4(auth.userStream, auth.protectionStatusStream, us_provider.activeStream, bloc.assistenceStream, (user, protectionStatus, ss, assistence) => {"user": user, "protectionStatus": protectionStatus, "ss": ss, "assistence": assistence}),
          builder: (BuildContext context, AsyncSnapshot<dynamic> data) {
            if(data.hasData && data.data["user"]!=null && data.data["ss"]!=null && data.data["protectionStatus"]!=null && data.data["assistence"]!=null) {
              final User user = data.data["user"];
              final SubscriptionSelection ss = data.data["ss"];
              final String protectionStatus = data.data["protectionStatus"];
              final List<UserAssistence> assistence = data.data["assistence"];

              final List<Widget> childrenRowButtons = (protectionStatus == "L") ? [_biommetricDisableButton(auth), _cambiarCuentaButton(us_provider)] : ((protectionStatus == "S") ? [_biommetricEnableButton(auth), _cambiarCuentaButton(us_provider)] : [_cambiarCuentaButton(us_provider)]);

              return Container(
                width: double.infinity,
                child: Column(
                  children: <Widget>[
                    _userHeader(context, user, ss),
                    SizedBox(height: 20),
                    Wrap(children: childrenRowButtons, spacing: 20, runSpacing: 20, alignment: WrapAlignment.center),
                    SizedBox(height: 20),
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        circleGraph(context, number: ss.us.wod_counter, max: ss.pricing.wod_counter, detail: "WODs"),
                        Expanded(child: SizedBox()),
                        circleGraph(context, number: ss.us.open_counter, max: ss.pricing.open_counter, detail: "Open"),
                        Expanded(child: SizedBox()),
                        circleGraph(context, number: ss.us.total_counter, max: ss.pricing.total_counter, detail: "Totales")
                      ]
                    ),
                    SizedBox(height: 20),
                    textRenew(!ss.pricing.recharge_weekly, context),
                    SizedBox(height: 20),
                    _asistenciaGraph(context, bloc, assistence, ss.box.id, user.id),
                    SizedBox(height: 40),
                    Column(
                      children: [
                        _configurationButton(context),
                        SizedBox(height: 30),
                        _logoutButton(context),
                        SizedBox(height: 30),
                        _bisualButton(context),
                      ],
                      mainAxisAlignment: MainAxisAlignment.center
                    ),
                    SizedBox(height: 20),
                  ],
                )
              );
            }
            else {
              final size_circle = MediaQuery.of(context).size.width/3.7;
              final size_button = MediaQuery.of(context).size.width/2.5;
              return Container(
                child: Column(
                  children: <Widget>[
                    neuSkeletonCard(150, double.infinity),
                    SizedBox(height: 20),
                    Row(children: <Widget>[
                      neuSkeletonCard(70, size_button),
                      Expanded(child: SizedBox()),
                      neuSkeletonCard(70, size_button),
                    ]),
                    SizedBox(height: 20),
                    Row(children: <Widget>[
                      neuSkeletonCircle(size_circle, size_circle),
                      Expanded(child: SizedBox()),
                      neuSkeletonCircle(size_circle, size_circle),
                      Expanded(child: SizedBox()),
                      neuSkeletonCircle(size_circle, size_circle)
                    ]),
                    SizedBox(height: 20),
                    neuSkeletonCard(350, double.infinity)
                  ],
                )
              );
            }
          }
        ),
      ),
    );
    
  }

  _userHeader(BuildContext context, User user, SubscriptionSelection ss) {
    return neuContainer(
      Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Hero(
            tag: 'edit-user-profile-image',
            child: Container( 
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                image: DecorationImage(
                  fit: BoxFit.cover,
                  image: CachedNetworkImageProvider(user.url_profile_photo!=null ? user.url_profile_photo : "https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQY8d3CgTZxxjmSAyYnXTS487Z-xbMxPOargPbKn9ojZAsy6pRI&usqp=CAU"),
                ),
                boxShadow: [BoxShadow(
                  color: neuShadowDarkColor,
                  blurRadius: 10,
                  spreadRadius: -2,
                  offset: Offset(3.0, 3.0, )
                )]
              ),
              width: 100,
              height: 100
            ),
          ),
          SizedBox(width: 20),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text("${user.name} ${user.surnames}", style: Theme.of(context).textTheme.title, overflow: TextOverflow.ellipsis,),
                SizedBox(height: 10),
                Text(ss.company.name, style: Theme.of(context).textTheme.body1, overflow: TextOverflow.ellipsis,),
                SizedBox(height: 10),
                neuButton(
                  NeumorphicButton(
                    boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
                    padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                    style: NeumorphicStyle(
                      color: colors['primary'],
                      depth: neuDepth,
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Icon(MyFlutterApp.pencil, color: colors["white"], size: 20),
                        SizedBox(width: 10),
                        Text("Editar perfil", style: Theme.of(context).textTheme.display2)
                      ],
                    ),
                    onClick: () {
                      Navigator.pushNamed(context, 'user-detail');
                    }
                  ),
                  borderRadius: BorderRadius.circular(30)
                )
              ]
            ),
          )
        ] 
      ),
      width: double.infinity
    );
  }

  _logoutButton(BuildContext context) => neuButton(
    NeumorphicButton(
      padding: EdgeInsets.all(20),
      style: neuButtonStyle(),
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(MyFlutterApp.logout, color: colors["text"], size: 20),
          SizedBox(width: 10),
          Text("Cerrar sesión"),
        ],
      ),
      onClick: () {
        final auth = Provider.of<AuthProvider>(context, listen: false);
        Navigator.pushReplacementNamed(context, 'login');
        auth.logout();
      },
    ),
    borderRadius: BorderRadius.circular(30),
    width: 160
  );

  _configurationButton(BuildContext context) => neuButton(
    NeumorphicButton(
      padding: EdgeInsets.all(20),
      style: neuButtonStyle(),
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(MyFlutterApp.gears, color: colors["text"], size: 20),
          SizedBox(width: 10),
          Text("Configuración"),
        ],
      ),
      onClick: () {
        Navigator.pushNamed(context, 'configuration');
      },
    ),
    borderRadius: BorderRadius.circular(30),
    width: 170
  );

  _biommetricEnableButton(final AuthProvider auth) => neuButton(
    NeumorphicButton(
      padding: EdgeInsets.all(20),
      style: neuButtonStyle(),
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
      child: shaderContainer(
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(Icons.fingerprint, color: colors["text"], size: 20),
            SizedBox(width: 10),
            Text("Activar protección"),
          ],
        ),
        'letter',
        [colors["primary"], colors["secondary"]]
      ),
      onClick: () {
        auth.protect();
      },
    ),
    borderRadius: BorderRadius.circular(30),
    width: 195
  );

  _biommetricDisableButton(final AuthProvider auth) => neuButton(
    NeumorphicButton(
      padding: EdgeInsets.all(20),
      style: neuButtonStyle(),
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
      child: shaderContainer(
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(Icons.fingerprint, color: colors["text"], size: 20),
            SizedBox(width: 10),
            Text("Desactivar protección"),
          ],
        ),
        'letter',
        [colors["primary"], colors["secondary"]]
      ),
      onClick: () {
        auth.removeProtectionWithCheck();
      },
    ),
    borderRadius: BorderRadius.circular(30),
    width: 215
  );

  _cambiarCuentaButton(UserSubscriptionsProvider us) => neuButton(
    NeumorphicButton(
      padding: EdgeInsets.all(20),
      style: neuButtonStyle(),
      boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(30)),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(MyFlutterApp.box, color: colors["text"], size: 20),
          SizedBox(width: 10),
          Text("Cambiar box"),
        ],
      ),
      onClick: () {
        us.openSubscriptionsDialog();
      },
    ),
    borderRadius: BorderRadius.circular(30),
    width: 155
  );

  static Widget circleGraph(BuildContext context, {int number, String detail, int max}) {
    final size = MediaQuery.of(context).size.width/3.7;
    if(detail == null) {
      return neuSkeletonCircle(size, size);
    }
    else return Container( 
      width: size,
      height: size,
      decoration: BoxDecoration(
        gradient: neuGradientInverse,
        shape: BoxShape.circle
      ),
      child: Neumorphic(
        style: NeumorphicStyle(
          color: Colors.transparent,
          shadowDarkColor: neuShadowDarkColor,
        ),
        boxShape: NeumorphicBoxShape.circle(),
        child: Align(
          alignment: Alignment.center,
          child: Stack(
            alignment: AlignmentDirectional.center,
            children: [
              SizedBox(width: size, height: size, child: Padding(padding: EdgeInsets.all(6), child: CircularProgressIndicator(value: (number==0 || max==0 || max==null || number==null ? 1 : number/max), strokeWidth: 3, valueColor: AlwaysStoppedAnimation(colors["primary"])))),
              RichText(text: TextSpan(
                style: Theme.of(context).textTheme.body1.copyWith(height: 1.2),
                children: [
                  TextSpan(text: number==null ? "∞\n" : number.toString() + "\n", style: number==null ? Theme.of(context).textTheme.title.copyWith(fontSize: 30) : Theme.of(context).textTheme.title),
                  TextSpan(text: detail)
                ]
              ), textAlign: TextAlign.center)
            ]
          )
        ),
      ),
    );
  }

  _asistenciaGraph(BuildContext context, UserPageBloc bloc, List<UserAssistence> data, int box_id, int user_id) {
    if(data.length==0) {
      return neuContainer(
        Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
          shaderContainer(Icon(MyFlutterApp.exhaust, size: 70,), 'letter', [colors["primary"], colors["secondary"]]),
          SizedBox(height: 50),
          Text("Vaya, no has entrenado últimamente...", style: Theme.of(context).textTheme.body1)
        ]),
        width: double.infinity,
        height: 250
      );
    }
    else {
      final double width = 7;
      final Color wodBarColor = colors["primary"];
      final Color openBarColor = colors["secondary"];

      Map<int, Map<String, double>> finalData = {
        0: {"y1": 0, "y2": 0},
        1: {"y1": 0, "y2": 0},
        2: {"y1": 0, "y2": 0},
        3: {"y1": 0, "y2": 0},
        4: {"y1": 0, "y2": 0},
        5: {"y1": 0, "y2": 0},
        6: {"y1": 0, "y2": 0},
      };

      double max = 0;
      data.forEach((element) {
        if(element.type=="open") finalData[element.weekday]["y2"] += element.count;
        else finalData[element.weekday]["y1"] += element.count;

        if(finalData[element.weekday]["y1"] > max) max = finalData[element.weekday]["y1"];
        if(finalData[element.weekday]["y2"] > max) max = finalData[element.weekday]["y2"];
      });

      List<BarChartGroupData> barGroups = List();
      finalData.forEach((k, v) { barGroups.add(
        BarChartGroupData(
          barsSpace: 4,
          x: k,
          barRods: [
            BarChartRodData(y: v["y1"], color: wodBarColor, width: width),
            BarChartRodData(y: v["y2"], color: openBarColor, width: width)
          ]
        )); 
      });

      return neuContainer(
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Row(children: <Widget>[
              Text("Asistencia", style: Theme.of(context).textTheme.title),
              SizedBox(width: 20),
              Expanded( child: NeumorphicToggle(
                style: NeumorphicToggleStyle(backgroundColor: neuColor, borderRadius: BorderRadius.circular(8)),
                height: 50.0,
                selectedIndex: _month==2 ? 1 : 0,
                displayForegroundOnlyIfSelected: true,
                children: [
                  ToggleElement(
                    background: Center( child: Text("Siempre") ),
                    foreground: Center( child: Text("Siempre") ),
                  ),
                  ToggleElement(
                    background: Center( child: Text("2 meses") ),
                    foreground: Center( child: Text("2 meses") )
                  ),
                ],
                thumb: Neumorphic(
                  style: neuStyle(),
                ),
                onChanged: (value) {
                  _month = value==0 ? null : 2;
                  if(_month==null) {
                    bloc.refreshAssistence(box_id, user_id);
                  }
                  else {
                    bloc.refreshAssistence(box_id, user_id, params: {"start_date": DateTime(_now.year, _now.month-_month, _now.day), "end_date": _now});
                  }
                },
              ))
            ],),
            SizedBox(height: 20),
            Column(children: <Widget>[
              Indicator(color: colors['primary'], text: 'WODs', isSquare: false),
              SizedBox(height: 4),
              Indicator(color: colors['secondary'], text: 'OpenBox', isSquare: false),
            ],),
            SizedBox(height: 20),
            BarChart(BarChartData(
              barGroups: barGroups,
              titlesData: FlTitlesData(
                show: true,
                bottomTitles: SideTitles(
                  showTitles: true,
                  getTitles: UtilsHAW.dayToMonthString,
                  margin: 20,
                  reservedSize: 0,
                  textStyle: Theme.of(context).textTheme.overline,
                ),
                leftTitles: SideTitles(
                  showTitles: true,
                  getTitles: (val) => val.toInt().toString(),
                  margin: 20,
                  reservedSize: 20,
                  interval: max>0 ? ((max/4)+1).floor().toDouble() : 1,
                  textStyle: Theme.of(context).textTheme.overline
                )
              ),
              borderData: FlBorderData( show: false )
            ))
          ],
        ),
        padding: EdgeInsets.symmetric(vertical: 35, horizontal: 30),
        width: double.infinity
      );
    }
  }

  static textRenew(bool esBono, BuildContext context) {
    return esBono ?
      Text("Contacta con tu box para conseguir más créditos.", style: Theme.of(context).textTheme.body1.copyWith(fontStyle: FontStyle.italic), textAlign: TextAlign.right) :
      Text("Los créditos semanales se renuevan cada Lunes entre 00.00h y 06.00h.", style: Theme.of(context).textTheme.body1.copyWith(fontStyle: FontStyle.italic), textAlign: TextAlign.right);
  }

  _bisualButton(BuildContext context) => GestureDetector(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("Creado por", style: Theme.of(context).textTheme.body1.copyWith(fontStyle: FontStyle.italic, fontSize: 14)),
        SizedBox(height: 10),
        Image(image: AssetImage("assets/icon/bisual.png"), height: 20),
      ]
    ),
    onTap: () async {
      if(await canLaunch("https://bisual.net")) {
        await launch("https://bisual.net", forceWebView: true);
      }
    },
  );

}