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

import 'package:dio/dio.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:naim/classes/appdata.dart';
import 'dart:ui';
import 'package:naim/classes/assets.dart';
import 'package:naim/screens/auth/createpass.dart';
import 'package:naim/screens/auth/pass.dart';
import 'package:naim/screens/profile_settings.dart';
import 'package:naim/widgets/input.dart';
import 'package:otp_text_field/otp_field.dart';
import 'package:otp_text_field/style.dart';

import '../../classes/Auth.dart';
import '../../classes/Authenticate.dart';
import '../home.dart';

class OtpPage extends StatefulWidget {
  @override
  OtpPage(this.phone);
  _OtpPageState createState() => _OtpPageState();

  final String phone;
}

class _OtpPageState extends State<OtpPage> {
  final String backImg = camobkimg;
  //final TextEditingController txtOtp = TextEditingController();
  OtpFieldController otpController = OtpFieldController();
  String txtOtp = "";
  String verificationId = "";
  String smsCode = "";
  bool isVerifying = false;
  bool isValidatingOtp = false;
  var timeleft = 60;
  late Timer _timer;
  String msg = "Please wait...";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    processPhoneAuth(context);
  }

  void startTimer() {
    int _start = 60000;
    setState(() {
      timeleft = 60;
    });
    const oneDecimal = Duration(milliseconds: 1000);
    setState(() {
      _timer = Timer.periodic(
          oneDecimal,
          (Timer timer) => setState(() {
                if (_start < 1000) {
                  _timer.cancel();
                  isVerifying = false;
                } else {
                  _start = _start - 1000;
                  //print(_start);
                  timeleft = timeleft - 1;
                }
              }));
    });
  }

  void verifiedSuccess(AuthCredential user) async {
    setState(() {
      isVerifying = false;
      if (_timer.isActive) {
        _timer.cancel();
      }
    });
    print("it hit verification complete");
    print("user " + user.toString());
    await FirebaseAuth.instance.signInWithCredential(user);

    GUser nuser = GUser();
    var b = await nuser.getCurrentUser();
    if (b["user"] != null) {
      handleSuccess();
    } else {
      showAlert(context, AlertDialogType.ERROR, "Error", b["msg"]);
    }
  }

  void smsCodeSent(String? verId, [int? forceCodeResend]) {
    print('setting verif ' + verId!);
    setState(() {
      verificationId = verId;
      msg = "OTP has been sent ";
    });

    /* smsCodeDialog(context).then((value) {
        print('Signed In');
      }); */
  }

  void autoRetrieve(String verId) {
    print('setting verif ' + verId);
    setState(() {
      verificationId = verId;
    });
  }

  void verifiedFailed(FirebaseAuthException exception) {
    setState(() {
      isVerifying = false;
      if (_timer.isActive) {
        _timer.cancel();
      }
    });

    showAlert(context, AlertDialogType.ERROR, "Something went wrong",
        '${exception.message}');
    otpController.clear();
  }

  void processPhoneAuth(BuildContext context) async {
    String phone = widget.phone;
    phone = regularizePhoneNumber(phone);
    setState(() {
      isVerifying = true;
      msg = "Please wait... ";
    });
    startTimer();

    await FirebaseAuth.instance.verifyPhoneNumber(
      phoneNumber: phone,
      codeAutoRetrievalTimeout: autoRetrieve,
      codeSent: smsCodeSent,
      timeout: const Duration(seconds: 5),
      verificationCompleted: verifiedSuccess,
      verificationFailed: verifiedFailed,
    );
  }

  handleSuccess() {
    if (appData.dbUser["username"] == "") {
      Navigator.of(context).pushAndRemoveUntil(
          MaterialPageRoute(builder: (context) => ProfileSettings(true)),
          (Route<dynamic> route) => false);
    } else {
      if (appData.dbUser["passkey"] == "") {
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (context) => CreatePassPage(true)),
            (Route<dynamic> route) => false);
      } else {
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (context) => UnlockPage(true)),
            (Route<dynamic> route) => false);
      }
    }
  }

  signIn() async {
    try {
      final AuthCredential credential = PhoneAuthProvider.credential(
          verificationId: verificationId, smsCode: txtOtp);

      await FirebaseAuth.instance
          .signInWithCredential(credential)
          .then((user) async {
        GUser nuser = GUser();
        var b = await nuser.getCurrentUser();
        if (b["user"] == null) {
          showAlert(context, AlertDialogType.ERROR, "Oops", b["msg"]);
          setState(() {
            isVerifying = false;
            msg = "Please wait...";
          });
          if (_timer.isActive) {
            _timer.cancel();
          }
          return;
        }

        if (_timer.isActive) {
          _timer.cancel();
        }
        handleSuccess();
      }).catchError((e) {
        print(e);
        showAlert(context, AlertDialogType.ERROR, "Oooops", e.message);
        setState(() {
          isValidatingOtp = false;
        });
      });
    } catch (e) {
      print("Error occured; " + e.toString());
    }
  }

  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: double.infinity,
        decoration: BoxDecoration(
            image:
                DecorationImage(image: AssetImage(backImg), fit: BoxFit.cover)),
        child: Stack(
          children: <Widget>[
            Center(
              child: Container(
                margin: const EdgeInsets.all(28.0),
                padding: const EdgeInsets.symmetric(
                    horizontal: 24.0, vertical: 48.0),
                decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.8),
                    borderRadius: BorderRadius.circular(10.0)),
                child: BackdropFilter(
                  filter: ImageFilter.blur(
                    sigmaX: 1.0,
                    sigmaY: 1.0,
                  ),
                  child: SingleChildScrollView(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Container(
                            width: 100,
                            height: 100,
                            child: Image.asset(appLogo)),
                        const SizedBox(height: 10.0),
                        const Text(
                          "Nigerian Army Instant Messenger",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              color: armyGreen,
                              fontSize: 24.0,
                              fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(height: 20.0),
                        Text("Please Enter OTP Sent to ${widget.phone}.",
                            textAlign: TextAlign.center,
                            style: const TextStyle(fontSize: 18.0)),
                        const SizedBox(height: 30.0),
                        SizedBox(
                          width: double.infinity,
                          child: OTPTextField(
                              controller: otpController,
                              length: 6,
                              width:
                                  MediaQuery.of(context).size.width - (48 + 52),
                              textFieldAlignment: MainAxisAlignment.spaceAround,
                              fieldWidth: (MediaQuery.of(context).size.width /
                                      6) -
                                  (MediaQuery.of(context).size.width * 0.06),
                              fieldStyle: FieldStyle.box,
                              outlineBorderRadius: 15,
                              style: TextStyle(fontSize: 17),
                              onChanged: (pin) {
                                //print("Changed: " + pin);
                              },
                              onCompleted: (pin) {
                                setState(() {
                                  txtOtp = pin;
                                });
                                print("Completed: " + pin);
                              }),
                        ),
                        const SizedBox(height: 30.0),
                        isVerifying
                            ? Text(msg + " " + timeleft.toString() + "s")
                            : getTextButton(
                                armyGreen, "Did not receive code? sent again",
                                () {
                                processPhoneAuth(context);
                              }),
                        const SizedBox(height: 30.0),
                        SizedBox(
                          width: double.infinity,
                          child: getElevatedButton(
                              armyGreen,
                              isValidatingOtp
                                  ? "Please Wait..."
                                  : "Validate OTP", () {
                            if (!isValidatingOtp) {
                              validateOtp(context);
                            }
                          }),
                        ),
                        const SizedBox(
                          height: 20,
                        ),
                        FlatButton(
                          textColor: armyGreen,
                          child: const Text("Enter a different Phone Number"),
                          onPressed: () {
                            if (_timer.isActive) {
                              _timer.cancel();
                            }
                            Navigator.of(context).pop();
                          },
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

  validateOtp(BuildContext context) async {
    setState(() {
      isValidatingOtp = true;
    });
    signIn();
    return;
    var user = FirebaseAuth.instance.currentUser;
    if (user != null) {
      GUser nuser = GUser();
      var b = await nuser.getCurrentUser();
      if (b["user"] != null) {
        handleSuccess();
      } else {
        showAlert(context, AlertDialogType.ERROR, "Sorry", b["msg"]);
        nuser.signOut();
        Navigator.of(context).pop();
      }
    } else {
      signIn();
    }
  }

  Future<bool> phoneNumberExist(String phone) async {
    try {
      var dio = Dio();
      dio.options.baseUrl = appApi;
      FormData formData = FormData.fromMap({"phone": phone});
      var response = await dio.post(
        "verifyphone",
        data: formData,
        options: Options(
          method: 'POST',
          responseType: ResponseType.plain,
          headers: {
            HttpHeaders.contentLengthHeader:
                formData.length, // set content-length
          },
        ),
      );
      print(response.data);
      var data = json.decode(response.data);
      if (data["result"] != null) {
        if (data["result"]['result'] == "success") {
          return true;
        }
      }
    } catch (e) {
      print("Error: " + e.toString());
    }
    return false;
  }
}
