part of '../pages.dart';

final user = RM.injectAuth<AuthModel?, LoginParam>(
  () => AuthRepository(),
  persist: () => PersistState<AuthModel?>(
    key: '__AuthModel__',
    toJson: (user) => user!.toJson(),
    fromJson: (json) {
      final user = AuthModel.fromJson(json);
      return user.data!.token != null ? user : null;
    },
    debugPrintOperations: true,
  ),
  autoSignOut: (user) {
    if (user!.data == null) {
      return Duration(seconds: 5);
    }
    return Duration(days: 3);
  },
  onSetState: On.error(
    (error, refresh) {
      String err = checkError(error.toString());
      showToastWidget(
        err,
        duration: 'long'
      );
    },
  ),
);

final RegExp _passwordRegExp = RegExp(
  r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$',
);

final RegExp _emailRegExp = RegExp(
  r'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
);

final _email = RM.injectTextEditing(
  validator: (email) {
    if (!_emailRegExp.hasMatch(email!)) {
      return "Enter a valid email";
    }
  },
);
final _password = RM.injectTextEditing(
  validateOnTyping: true,
  validator: (password) {
    if (password!.length < 4) {
      return "Enter a valid password";
    }
  },
);

final _form = RM.injectForm(
  submit: () async {
    await user.auth.signIn(
      (_) => LoginParam(
        email: _email.text,
        password: _password.text,
      ),
      onError: (error, refresh) {
        showToastWidget(
          error.message,
          duration: 'long'
        );
      }
    );
    if (user.error != null) {
      showToastWidget(
        user.error.message,
        duration: 'long'
      );
    }
  },
);

class AuthException implements Exception {
  final String message;
  AuthException(this.message);
}

class LoginDynamicPage extends StatefulWidget {
  const LoginDynamicPage({Key? key}) : super(key: key);
  static const routeName = '/login_dynamic_page';

  @override
  _LoginDynamicPageState createState() => _LoginDynamicPageState();
}

class _LoginDynamicPageState extends State<LoginDynamicPage> {
  Map<String, dynamic> variables = {
    "listenToFormState": _form,
    "emailFieldKey": Key('__EmailField__'),
    "emailController": _email.controller,
    "emailFocusNode": _email.focusNode,
    "emailErrorText": _email.error,
    "passwordFieldKey": Key('__PasswordField__'),
    "passwordController": _password.controller,
    "passwordFocusNode": _password.focusNode,
    "passwordErrorText": _password.error,
    "submitFocusNode": _form.submitFocusNode
  };

  final pageJson = '''
  {
    "widget": "Scaffold",
    "body": {
      "widget": "Padding",
      "padding": "10.0,10.0,10.0,10.0",
      "child": {
        "widget": "Onform",
        "child": {
          "widget": "Column",
          "mainAxisAlignment": "center",
          "crossAxisAlignment": "stretch",
          "children": [
            {
              "widget": "TextField",
              "key": "emailFieldKey",
              "controller": "emailController",
              "focusNode": "emailFocusNode",
              "decoration": {
                "icon": {
                  "widget": "Icon",
                  "data": "email"
                },
                "labelText": "Email",
                "errorText": "emailErrorText"
              },
              "keyboardType": "emailAddress",
              "autocorrect": false,
              "onSubmitted": {
                "function": "emailOnSubmitted"
              }
            },
            {
              "widget": "TextField",
              "key": "passwordFieldKey",
              "controller": "passwordController",
              "focusNode": "passwordFocusNode",
              "decoration": {
                "icon": {
                  "widget": "Icon",
                  "data": "lock"
                },
                "labelText": "Password",
                "errorText": "passwordErrorText"
              },
              "obscureText": true,
              "autocorrect": false,
              "onSubmitted": {
                "function": "passwordOnSubmitted"
              }
            },
            {
              "widget": "SizedBox",
              "height": 10.0
            },
            {
              "widget": "OnformSubmission",
              "onSubmitting": {
                "widget": "Center",
                "child": {
                  "widget": "CircularProgressIndicator"
                }
              },
              "child": {
                "widget": "LLSButton",
                "size": "small",
                "text": "Sign In",
                "textColor": "lls_white",
                "onPressed": { 
                  "function": "submitOnPressed"
                }
              },
              "state": "listenToFormState"
            },
            {
              "widget": "SizedBox",
              "height": 10.0
            }
          ]
        },
        "state": "listenToFormState"
      }
    }
  }
  ''';

  Widget _buildErrorPage(String error, BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                error,  
                style: TextStyle(fontSize: 14),
              ),
            ),
            const SizedBox(
              height: 15
            ),
            LLSButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text(
                'Back',
                style: TextStyle(fontSize: 16),
              ),
              type: LLSButtonType.outline,
              color: LLSColors.SUCCESS,
            ),
          ]
        ),
      )
    );
  }

  Future<Widget?> _buildWidget(BuildContext context) async {
    try {
      return WidgetParserBuilder.build(pageJson, context, LoginPageMethodListener(), variables);
    } catch (e) {
      String err = e.toString();
      return _buildErrorPage(err, context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Widget?>(
      future: _buildWidget(context),
      builder: (BuildContext context, AsyncSnapshot<Widget?> snapshot) {
        if (snapshot.hasError) {
          return _buildErrorPage(snapshot.error.toString(), context);
        }
        return snapshot.hasData ? snapshot.data! : Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                CircularProgressIndicator()
              ]
            ),
          )
        );
      },
    );
  }
}

class LoginPageMethodListener extends MethodListener {
  @override
  run(BuildContext context, Map<String, dynamic>? event) {
    if (isFunctionNameExist(event)) {
      if (event!['function'] == 'emailOnSubmitted') {
        _password.focusNode.requestFocus();
      } else if (event['function'] == 'passwordOnSubmitted') {
        _form.submitFocusNode.requestFocus();
      } else if (event['function'] == 'submitOnPressed') {
        _form.submit();
      }
    } else {
      print("receiver event: ${event.toString()}");
    }
  }
}