


import 'package:app_hit_a_wod/src/models/user.model.dart';
import 'package:app_hit_a_wod/src/providers/api.provider.dart';
import 'package:app_hit_a_wod/src/models/subscription_selection.model.dart';
import 'package:app_hit_a_wod/src/providers/auth.provider.dart';
import 'package:app_hit_a_wod/src/styles.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'dart:io' show Platform;

class LoginFormBloc {

  BuildContext _context;
  AuthProvider _auth;
  ApiProvider _api;
  bool _isSuperAdmin = false;

  BehaviorSubject<String> _statusSubject = new BehaviorSubject(); //'init', 'loading', 'done'
  Stream<String> get statusStream => _statusSubject.stream;
  BehaviorSubject<String> _emailSubject = new BehaviorSubject();
  Stream<String> get emailStream => _emailSubject.stream;
  get setEmail => _emailSubject.sink.add;
  BehaviorSubject<String> _passwordSubject = new BehaviorSubject();
  Stream<String> get passwordStream => _passwordSubject.stream;
  get setPassword => _passwordSubject.sink.add;
  BehaviorSubject<String> _customUserId = new BehaviorSubject();
  Stream<String> get customUserIdStream => _customUserId.stream;
  get setCustomUserId => _customUserId.sink.add;

  static LoginFormBloc _instancia;
  factory LoginFormBloc(BuildContext context, AuthProvider auth) {
    if(_instancia==null) _instancia = LoginFormBloc._internal(context, auth);
    else _instancia._context = context;

    return _instancia;
  }
  LoginFormBloc._internal(BuildContext this._context, AuthProvider this._auth) {
    _api = Provider.of<ApiProvider>(this._context);
    _statusSubject.sink.add('init');
    _customUserId.sink.add(null);
    _initTokenListener();
  }

  refresh() {
    this._auth.refreshToken();
  }

  login() async {
    _statusSubject.sink.add('loading');
    try {
      var resp = await _auth.login(_emailSubject.value, _passwordSubject.value, custom_user_id: _customUserId.value);
      _statusSubject.sink.add('init');
      if(resp.subscriptions.length == 0) Navigator.pushReplacementNamed(_context, 'no-subscriptions');
      else if(AuthProvider.isSuperAdmin(resp.subscriptions)) {
        _isSuperAdmin = true;
        if (Platform.isAndroid) _oneSignalId(resp.user);
        showSuperadminDialog();
      } else {
        if(!_isSuperAdmin && Platform.isAndroid) _oneSignalId(resp.user);
        Navigator.pushReplacementNamed(_context, 'home');
      }
    } on DioError catch(e) {
      _statusSubject.sink.add('init');
      _statusSubject.sink.addError(e.response!=null ? e.response.data["error"] : e.toString());
      return false;
    } on Exception catch(e) {
      _statusSubject.sink.add('init');
      _statusSubject.sink.addError(e.toString());
      return false;
    }
  }

  _initTokenListener() {
    this._auth.tokenStream.first.then((value) async {
      if(value.fromStorage) {
        _statusSubject.sink.add('loading');
        try {
          var resp = await this._auth.refreshToken();
          _statusSubject.sink.add('init');
          if(resp.subscriptions.length == 0) Navigator.pushReplacementNamed(_context, 'no-subscriptions');
          else if(AuthProvider.isSuperAdmin(resp.subscriptions)) {
            _auth.logout();
            showSuperadminDialog();
          }
          else Navigator.pushReplacementNamed(_context, 'home');
        } on Exception catch(e) {
          _statusSubject.sink.add('init');
          _statusSubject.sink.addError("No se ha podido renovar la sesión. Vuelve a entrar por favor.");
          return false;
        }
      }
    });
  }
 
  void showSuperadminDialog() {
    neuDialog(
      context: this._context,
      padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
      child: Column(
        children: <Widget>[
          Text("Has iniciado como super administrador de Hit a Wod. \n\nIntroduce el identificador de usuario con el que quieres iniciar sesión: ", style: Theme.of(this._context).textTheme.body1),
          SizedBox(height: 20),
          neuInput(TextFormField(
            cursorColor: Color.fromRGBO(141, 39, 144, 1),
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
              border: InputBorder.none,
              hintText: 'Identificador de usuario'
            ),
            textInputAction: TextInputAction.send,
            onChanged: this.setCustomUserId,
          )),
          SizedBox(height: 20),
          neuButton(NeumorphicButton(
            padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
            boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(40)),
            style: NeumorphicStyle( color: colors['primary'] ),
            child: Text("Iniciar sesión", style: Theme.of(this._context).textTheme.display2, textAlign: TextAlign.center),
            onClick: () {
              if(this._customUserId.value != null) {
                this.login();
                Navigator.of(this._context).pop(); //close dialog
              }
            }
          ), width: double.infinity)
        ]
      ));
  }

  _oneSignalId(User user) async {
    var status = await OneSignal.shared.getPermissionSubscriptionState();
    var playerId = status.subscriptionStatus.userId;
    _api.updateOneSignalPlayerId(user.id, playerId);
    print("one signal player id" + playerId);
  }

}