import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:memorias_calculo/src/back/providers/login_ventilacion_provider.dart';
import 'package:memorias_calculo/src/back/providers/nueva_cuenta_provider.dart';
import 'package:memorias_calculo/src/back/scoped_models/user_info_model.dart';
import 'package:memorias_calculo/src/front/pages/verificacion_page.dart';
import 'package:memorias_calculo/src/front/widgets/cargando.dart';
import 'package:memorias_calculo/src/front/widgets/formatters.dart';
import 'package:scoped_model/scoped_model.dart';

class FormularioUsuarioPage extends StatefulWidget {
  @override
  _FormularioUsuarioPageState createState() => _FormularioUsuarioPageState();
}

class _FormularioUsuarioPageState extends State<FormularioUsuarioPage> {
  final _loginVentilacionProvider = LoginVentilacionProvider();
  final List<String> _paises = [];
  final Map<String, String> _paisContinente = {};
  final Map<String, String> _continentes = {
    "EUR" : "Europa",
    "ASI" : "Asia",
    "AFR" : "Africa",
    "OCE" : "Oceanía",
    "AMN" : "América del norte",
    "AMS" : "América del sur",
    "AMC" : "América central"
  };
  final Map<String, List<String>> _estados = {};
  final Map<String, Map<String, List<String>>> _municipios = {};
  bool _isLoading = true;
  bool _tieneCuenta = true;
  bool _correoValido = true;
  bool _contraValida = true;
  bool _numeroValido = true;
  bool _contrasIguales = true;
  bool _esperando = false;
  bool _tieneEstados = true;
  bool _tieneCiudades = true;
  bool _numCliente = true;
  String _esDistribuidor = "No";
  String _pais = "";
  String _paisCode = "";
  String _estado = "";
  String _estadoCode = "";
  String _municipio = "";
  String _idUsuario = "";
  String _accessToken = "";
  String _continenteAct = "AMN";
  final Map<String, bool> _errores = {
    "nombre": false,
    "ciudad": false,
    "numTel": false,
    "correo": false,
    "contra": false,
    "confContra": false,
    "estado": false,
    "raSoc": false
  };
  final NuevaCuentaProvider _nuevaCuentaProvider = NuevaCuentaProvider();

  final TextEditingController _nombreController = TextEditingController();
  final TextEditingController _ciudadController = TextEditingController();
  final TextEditingController _numTelController = TextEditingController();
  final TextEditingController _correoController = TextEditingController();
  final TextEditingController _contraController = TextEditingController();
  final TextEditingController _confContraController = TextEditingController();

  final TextEditingController _estadoController = TextEditingController();
  final TextEditingController _raSocController = TextEditingController();

  @override
  void initState() {
    super.initState();
    readJson().then((value) => setState(() => _isLoading = false));
  }

  Future<void> readJson() async{
    final String paisesEstados = await rootBundle.loadString('assets/paises_db_simple.json');
    final String municipios = await rootBundle.loadString('assets/paises_db.json');
    final String munMex = await rootBundle.loadString('municipios_mx.json');

    final paisesEstadosArr = await jsonDecode(paisesEstados);
    final paises = paisesEstadosArr['paises'];
    final estados = paisesEstadosArr['estados'];

    paises.forEach((pais){
      _paisContinente[pais['CountryCode']] = pais['ContinentCode'];
      _paises.add("${pais['CountryName']} (${pais['CountryCode']})");
    });

    estados.forEach((estado){
      final pais = _estados[estado['SUCountry']];
      if(pais == null){
        _estados[estado['SUCountry']] = ["${estado['SUName'].trim()} (${estado['SUCode']})"];
      }else{
        pais.add("${estado['SUName'].trim()} (${estado['SUCode']})");
        _estados[estado['SUCountry']] = pais;
      }
    });

    final munMexDec = await jsonDecode(munMex);
    final munIntDec = await jsonDecode(municipios);

    munIntDec[0]["data"].forEach((item){
      final pais = _municipios[item["Country"]];
      if(pais == null){
        _municipios[item["Country"]] = {};
      }

      if(item["Subdivision"] != null) {
        final tmpEsta = _municipios[item["Country"]]![item["Subdivision"]];

        if(tmpEsta == null){
          _municipios[item["Country"]]![item["Subdivision"]] = [item["Name"]];
        }else{
          tmpEsta.add(item["Name"]);
          _municipios[item["Country"]]![item["Subdivision"]] = tmpEsta;
        }
      }
    });

    final municipiosMx = munMexDec["c_Municipio"];
    Map<String, List<String>> tmpMunMx = {};

    municipiosMx.forEach((municipioMx){
      final tmpEdoMx = tmpMunMx[municipioMx["c_Estado"]];

      if(tmpEdoMx == null){
        tmpMunMx[municipioMx["c_Estado"]] = [municipioMx["Descripción"]];
      }else{
        tmpEdoMx.add(municipioMx["Descripción"]);
        tmpMunMx[municipioMx["c_Estado"]] = tmpEdoMx;
      }
    });

    _municipios["MX"]!["MOR"] = tmpMunMx["MOR"]!;
  }

  Future<bool> registrarInfo(String nombre, String pais, String estado, String ciudad, String movil, String correo, String contra) async{
    final registro = await _nuevaCuentaProvider.registrarNuevaCuenta(
        nombre,
        pais,
        estado,
        ciudad,
        movil,
        correo,
        contra
    );

    Fluttertoast.showToast(
        msg: registro.message,
        toastLength: Toast.LENGTH_SHORT,
        timeInSecForIosWeb: 4,
        gravity: ToastGravity.CENTER,
        webBgColor: registro.response ? "linear-gradient(to right, #266B1F, #98F58F)" : "linear-gradient(to right, #b40404, #ff0000)"
    );

    _idUsuario = registro.result.idUsuario;
    _accessToken = registro.result.token;

    return registro.response;
  }

  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<UserInfoModel>(
      builder: (context, child, model){
        return Scaffold(
          body: _isLoading ? Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const CircularProgressIndicator(),
                const SizedBox(
                  height: 8.0,
                ),
                Cargando(
                  text: "Cargando datos del sistema.",
                )
              ],
            ),
          ) : LayoutBuilder(
            builder: (context , constraints){
              final parentHeight = constraints.maxHeight;
              final parentWidth = constraints.maxWidth;

              List<String> paisesDrop = [];
              _paises.forEach((pais) {
                final codeArr = pais.split(" ");
                String code = codeArr.last;
                code = code.replaceAll("(", "");
                code = code.replaceAll(")", "");

                String flag = code.toUpperCase();
                flag = flag.replaceAllMapped(RegExp(r'[A-Z]'), (match) => String.fromCharCode(match.group(0)!.codeUnitAt(0) + 127397));

                final continente = _paisContinente[code];
                if(continente == _continenteAct && code != "MX"){
                  paisesDrop.add("$flag - $pais");
                }
              });

              if(_continenteAct == "AMN"){
                const codeMx = "MX";
                final flag = codeMx.replaceAllMapped(RegExp(r'[A-Z]'), (match) => String.fromCharCode(match.group(0)!.codeUnitAt(0) + 127397));
                paisesDrop.insert(0, "$flag - México (MX)");
              }

              double containerWidth = parentWidth > 1440
                  ? parentWidth*0.5 : parentWidth > 1280 && parentWidth <= 1440
                  ? parentWidth*0.6 : parentWidth > 1080 && parentWidth <= 1280
                  ? parentWidth*0.75 : parentWidth > 900 && parentWidth <= 1080
                  ? parentWidth*0.8 : parentWidth > 720 && parentWidth <= 900
                  ? parentWidth*0.85 : parentWidth > 540 && parentWidth <= 720
                  ? parentWidth*0.9 : parentWidth;
              double containerMargin = (parentWidth - containerWidth) / 2;

              return SizedBox(
                width: parentWidth,
                height: parentHeight,
                child: SingleChildScrollView(
                  child: Container(
                    width: containerWidth,
                    margin: EdgeInsets.symmetric(
                      horizontal: containerMargin,
                    ),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        const SizedBox(
                          height: 32.0,
                        ),
                        Row(
                          children: [
                            const SizedBox(width: 32.0),
                            Image.asset(
                              "logo.png",
                              width: 64.0,
                            ),
                            Expanded(child: Container()),
                            Image.asset(
                              "logo_completo.png",
                              height: 64.0,
                            ),
                            const SizedBox(width: 32.0),
                          ],
                        ),
                        const SizedBox(
                          height: 32.0,
                        ),
                        Image.asset(
                          "matriz.png",
                          width: 120.0,
                          fit: BoxFit.cover,
                        ),
                        const SizedBox(
                          height: 48.0,
                        ),
                        Container(
                          width: double.infinity,
                          padding: const EdgeInsets.symmetric(
                            horizontal: 32.0,
                          ),
                          child: const Text(
                            "PORTAL DE MEMORIAS DE CÁLCULO",
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              fontFamily: "Helvetica Neue Black Cond",
                              fontSize: 28.0,
                            ),
                          ),
                        ),
                        const SizedBox(
                          height: 8.0,
                        ),
                        AnimatedContainer(
                          duration: const Duration(
                            milliseconds: 250,
                          ),
                          padding: const EdgeInsets.symmetric(horizontal: 32.0),
                          width: double.infinity,
                          child: Text(
                            _tieneCuenta
                                ? "Para usar este módulo es necesario tener una cuenta, por favor proporciona tus datos para continuar:"
                                : "Completa el siguiente formulario para crear tu cuenta:",
                            textAlign: TextAlign.center,
                            style: const TextStyle(
                              fontFamily: "Helvetica Neue Light",
                              fontSize: 22.0,
                              fontWeight: FontWeight.w600,
                              color: Color.fromRGBO(104, 104, 104, 1),
                            ),
                          ),
                        ),
                        const SizedBox(
                          height: 32.0,
                        ),
                        AnimatedContainer(
                          duration: const Duration(
                            milliseconds: 250,
                          ),
                          width: double.infinity,
                          margin: const EdgeInsets.symmetric(horizontal: 32.0),
                          child: Column(
                            children: [
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Nombre completo:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: TextField(
                                          controller: _nombreController,
                                          decoration: InputDecoration(
                                            hintText: "Juan Pérez",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["nombre"]! ? "*Campo obligatorio." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              color: const Color(0xFFFF0000),
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          onChanged: (value) => setState(() => _errores["nombre"] = false),
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Es distribuidor:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Container(
                                      padding: const EdgeInsets.only(left: 16.0),
                                      child: DropdownButton<String>(
                                        value: _esDistribuidor,
                                        onChanged: (val) => setState(() => _esDistribuidor = val!),
                                        items: ["Si", "No"].map((e) => DropdownMenuItem<String>(
                                          value: e,
                                          child: Text(
                                            e,
                                            style: GoogleFonts.roboto(),
                                          ),
                                        )).toList(),
                                      ),
                                    ),
                                    const SizedBox(
                                        width: 8.0,
                                      ),
                                    if(_esDistribuidor == "Si")
                                      Text(
                                        "# de Cliente:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    if(_esDistribuidor == "Si")
                                      const SizedBox(
                                        width: 8.0,
                                      ),
                                    if(_esDistribuidor == "Si")
                                      Switch(
                                        value: _numCliente,
                                        onChanged: (val) => setState(() => _numCliente = val),
                                        activeColor: const Color.fromRGBO(180, 4, 4, 1),
                                        activeTrackColor: const Color.fromRGBO(180, 4, 4, 0.75),
                                      ),
                                    Expanded(
                                      child: AnimatedContainer(
                                        child: TextField(
                                          controller: _raSocController,
                                          decoration: InputDecoration(
                                            hintText: _numCliente && _esDistribuidor == "Si" ? "Introduzca su número de cliente (Ej. 12345)." : "Introduzca la razón social de su empresa.",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["raSoc"]! ? "*Campo obligatorio." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              color: const Color(0xFFFF0000),
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          inputFormatters: [if(_numCliente) DecimalTextInputFormatter()],
                                          onChanged: (value) => setState(() => _errores["raSoc"] = false),
                                        ),
                                        duration: const Duration(
                                          milliseconds: 250,
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "País:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: DropdownButton<String>(
                                          value: _pais.isEmpty ? null : _pais,
                                          hint: Text(
                                            "Selecciona una opción",
                                            style: GoogleFonts.roboto(
                                                color: Colors.grey,
                                                fontStyle: FontStyle.italic
                                            ),
                                          ),
                                          onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
                                          onChanged: (nuevoPais) => setState((){
                                            _estado = "";
                                            _municipio = "";
                                            _estadoCode = "";
                                            _pais = nuevoPais!;
                                            _paisCode = nuevoPais.split(" ").last.replaceAll("(", "").replaceAll(")", "");

                                            _tieneEstados = _estados[_paisCode] != null;
                                          }),
                                          items: paisesDrop.map((e) => DropdownMenuItem<String>(
                                            child: Text(
                                              e,
                                              style: GoogleFonts.roboto(),
                                            ),
                                            value: e,
                                          )).toList(),
                                          isExpanded: true,
                                        ),
                                      ),
                                    ),
                                    const SizedBox(width: 16.0),
                                    Text(
                                      "Región:",
                                      textAlign: TextAlign.right,
                                      style: GoogleFonts.roboto(
                                        color: const Color.fromRGBO(102, 102, 102, 1),
                                        fontWeight: FontWeight.bold,
                                        fontSize: 16.0,
                                      ),
                                    ),
                                    const SizedBox(width: 16.0),
                                    DropdownButton<String>(
                                      items: _continentes.keys.toList().map((e) => DropdownMenuItem<String>(
                                        child: Text(
                                          _continentes[e]!,
                                          style: GoogleFonts.roboto(),
                                        ),
                                        value: e,
                                      )).toList(),
                                      value: _continenteAct,
                                      onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
                                      onChanged: (val) => setState((){
                                        _pais = "";
                                        _municipio = "";
                                        _estado = "";
                                        _paisCode = "";
                                        _estadoCode = "";
                                        _continenteAct = val!;
                                      }),
                                    )
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Estado:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: _tieneEstados ? DropdownButton<String>(
                                          value: _estado.isEmpty ? null : _estado,
                                          onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
                                          hint: Text(
                                            "Selecciona una opción",
                                            style: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                          ),
                                          disabledHint: Text(
                                            "Seleccion un país primero",
                                            style: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                          ),
                                          onChanged: _paisCode.isEmpty ? null : (nuevoEstado) => setState((){
                                            _municipio = "";
                                            _ciudadController.clear();
                                            _estado = nuevoEstado!;
                                            _estadoController.text = _estado;
                                            final code = nuevoEstado.split(" ").last.replaceAll("(", "").replaceAll(")", "");
                                            _estadoCode = code;

                                            _tieneCiudades = _municipios[_paisCode]![_estadoCode] != null;
                                          }),
                                          items: _paisCode.isEmpty ? null : _estados[_paisCode]!.map((e) => DropdownMenuItem<String>(
                                            child: Text(
                                              e,
                                              style: GoogleFonts.roboto(),
                                            ),
                                            value: e,
                                          )).toList(),
                                          isExpanded: true,
                                        ) : TextField(
                                          controller: _estadoController,
                                          decoration: InputDecoration(
                                            hintText: "Introduce el nombre de tu provincia",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["estado"]! ? "*Campo obligatorio." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              color: const Color(0xFFFF0000),
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          onChanged: (value) => setState(() => _errores["estado"] = false),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Ciudad:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: !_tieneEstados || !_tieneCiudades ? TextField(
                                          controller: _ciudadController,
                                          decoration: InputDecoration(
                                            hintText: "Introduce el nombre de tu ciudad",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["ciudad"]! ? "*Campo obligatorio." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              color: const Color(0xFFFF0000),
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          onChanged: (value) => setState(() => _errores["ciudad"] = false),
                                        ) : DropdownButton<String>(
                                          value: _municipio.isEmpty ? null : _municipio,
                                          onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
                                          hint: Text(
                                            "Selecciona una opción",
                                            style: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                          ),
                                          disabledHint: _paisCode.isEmpty ? Text(
                                            "Seleccion un país primero",
                                            style: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                          ) : Text(
                                            "Seleccion un estado primero",
                                            style: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                          ),
                                          onChanged: _estadoCode.isEmpty ? null : (nuevoMun) => setState((){
                                            _municipio = nuevoMun!;
                                            _ciudadController.text = _municipio;
                                          }),
                                          items: _estadoCode.isEmpty ? null : _municipios[_paisCode]![_estadoCode]!.map((e) => DropdownMenuItem<String>(
                                            child: Text(
                                              e,
                                              style: GoogleFonts.roboto(),
                                            ),
                                            value: e,
                                          )).toList(),
                                          isExpanded: true,
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Teléfono Móvil:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: TextField(
                                          controller: _numTelController,
                                          maxLength: _paisCode == "MX" ? 10 : null,
                                          keyboardType: TextInputType.number,
                                          decoration: InputDecoration(
                                            hintText: "7771234567",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["numTel"]! ? "*Campo obligatorio." : !_numeroValido ? "El número telefónico no tiene un formato válido." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          onChanged: (value) => setState((){
                                            _errores["numTel"] = false;

                                            const pattern = r'(^(?:[+0]9)?[0-9]{10,12}$)';
                                            final regExp = RegExp(pattern);

                                            _numeroValido = _paisCode == "MX" ? regExp.hasMatch(value) : true;
                                          }),
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                              Row(
                                children: [
                                  SizedBox(
                                    width: containerWidth*0.25,
                                    child: Text(
                                      "Correo electrónico:",
                                      textAlign: TextAlign.right,
                                      style: GoogleFonts.roboto(
                                        color: const Color.fromRGBO(102, 102, 102, 1),
                                        fontWeight: FontWeight.bold,
                                        fontSize: 16.0,
                                      ),
                                    ),
                                  ),
                                  Expanded(
                                    child: Container(
                                      padding: const EdgeInsets.only(left: 16.0),
                                      child: TextField(
                                        controller: _correoController,
                                        keyboardType: TextInputType.emailAddress,
                                        decoration: InputDecoration(
                                          hintText: "ejemplo@ejemplo.com",
                                          hintStyle: GoogleFonts.roboto(
                                            color: Colors.grey,
                                            fontStyle: FontStyle.italic,
                                          ),
                                          errorText: _errores["correo"]! ? "*Campo obligatorio." : !_correoValido ? "El correo tiene un formato inválido." : null,
                                          errorStyle: GoogleFonts.roboto(
                                            fontSize: 12.0,
                                          ),
                                        ),
                                        style: GoogleFonts.roboto(),
                                        onChanged: (value) => setState((){
                                          _errores["correo"] = false;

                                          const pattern = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
                                          final regExp = RegExp(pattern);

                                          _correoValido = regExp.hasMatch(value);
                                        }),
                                      ),
                                    ),
                                  )
                                ],
                              ),
                              const SizedBox(height: 8.0),
                              Row(
                                children: [
                                  SizedBox(
                                    width: containerWidth*0.25,
                                    child: Text(
                                      "Contraseña:",
                                      textAlign: TextAlign.right,
                                      style: GoogleFonts.roboto(
                                        color: const Color.fromRGBO(102, 102, 102, 1),
                                        fontWeight: FontWeight.bold,
                                        fontSize: 16.0,
                                      ),
                                    ),
                                  ),
                                  Expanded(
                                    child: Container(
                                      padding: const EdgeInsets.only(left: 16.0),
                                      child: TextField(
                                        controller: _contraController,
                                        obscureText: true,
                                        decoration: InputDecoration(
                                          hintText: "Ingrese una contraseña nueva (min. 8 caracteres)",
                                          hintStyle: GoogleFonts.roboto(
                                            color: Colors.grey,
                                            fontStyle: FontStyle.italic,
                                          ),
                                          errorText: _errores["contra"]! ? "*Campo obligatorio." : !_contraValida ? "La contraseña debe tener más de 8 caracteres." : null,
                                          errorStyle: GoogleFonts.roboto(
                                            fontSize: 12.0,
                                          ),
                                        ),
                                        style: GoogleFonts.roboto(),
                                        enableInteractiveSelection: false,
                                        onChanged: (value) => setState((){
                                          _errores["contra"] = false;

                                          _contraValida = value.length >= 8;
                                        }),
                                      ),
                                    ),
                                  )
                                ],
                              ),
                              const SizedBox(height: 8.0),
                              if(!_tieneCuenta)
                                Row(
                                  children: [
                                    SizedBox(
                                      width: containerWidth*0.25,
                                      child: Text(
                                        "Confirmar contraseña:",
                                        textAlign: TextAlign.right,
                                        style: GoogleFonts.roboto(
                                          color: const Color.fromRGBO(102, 102, 102, 1),
                                          fontWeight: FontWeight.bold,
                                          fontSize: 16.0,
                                        ),
                                      ),
                                    ),
                                    Expanded(
                                      child: Container(
                                        padding: const EdgeInsets.only(left: 16.0),
                                        child: TextField(
                                          controller: _confContraController,
                                          obscureText: true,
                                          keyboardType: TextInputType.emailAddress,
                                          decoration: InputDecoration(
                                            hintText: "Confirme su contraseña",
                                            hintStyle: GoogleFonts.roboto(
                                              color: Colors.grey,
                                              fontStyle: FontStyle.italic,
                                            ),
                                            errorText: _errores["confContra"]! ? "*Campo obligatorio." : !_contrasIguales ? "Las contraseñas no coinciden." : null,
                                            errorStyle: GoogleFonts.roboto(
                                              fontSize: 12.0,
                                            ),
                                          ),
                                          style: GoogleFonts.roboto(),
                                          enableInteractiveSelection: false,
                                          onChanged: (value) => setState((){
                                            _errores["confContra"] = false;
                                            _contrasIguales = true;
                                          }),
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              if(!_tieneCuenta)
                                const SizedBox(height: 8.0),
                            ],
                          ),
                        ),
                        const SizedBox(
                          height: 32.0,
                        ),
                        Container(
                          width: double.infinity,
                          margin: const EdgeInsets.symmetric(horizontal: 32.0),
                          child: Row(
                            children: [
                              MaterialButton(
                                elevation: 4.0,
                                padding: const EdgeInsets.symmetric(vertical: 16.0),
                                minWidth: (containerWidth/2)-32,
                                color: const Color(0xFFFF0000),
                                child: _tieneCuenta ? Row(
                                  children: [
                                    Image.asset(
                                      "quiero-una-cuenta.png",
                                      width: 32.0,
                                    ),
                                    const SizedBox(width: 8.0),
                                    const Text(
                                      "¡Quiero una cuenta!",
                                      style: TextStyle(
                                        fontFamily: "Helvetica Neue Black Cond",
                                        fontSize: 28.0,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ],
                                ) : Row(
                                  children: [
                                    Image.asset(
                                      "ya-tengo-una-cuenta.png",
                                      width: 32.0,
                                    ),
                                    const SizedBox(width: 8.0),
                                    const Text(
                                      "Ya tengo una cuenta",
                                      style: TextStyle(
                                        fontFamily: "Helvetica Neue Black Cond",
                                        fontSize: 28.0,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ],
                                ),
                                onPressed: () => setState(() {
                                  _tieneCuenta = !_tieneCuenta;

                                  _nombreController.clear();
                                  _paisCode = "";
                                  _estadoCode = "";
                                  _pais = "";
                                  _estado = "";
                                  _municipio = "";
                                  _numTelController.clear();
                                  _confContraController.clear();

                                  FocusScope.of(context).requestFocus(FocusNode());
                                }),
                              ),
                              const SizedBox(width: 16.0),
                              MaterialButton(
                                  elevation: 4.0,
                                  padding: const EdgeInsets.symmetric(vertical: 16.0),
                                  minWidth: (containerWidth/2)-32,
                                  color: const Color(0xFFFF0000),
                                  child: _tieneCuenta ? Row(
                                    children: [
                                      Image.asset(
                                        "iniciar-sesion.png",
                                        width: 32.0,
                                      ),
                                      const SizedBox(width: 8.0),
                                      const Text(
                                        "Iniciar sesión",
                                        style: TextStyle(
                                          fontFamily: "Helvetica Neue Black Cond",
                                          fontSize: 28.0,
                                          color: Colors.white,
                                        ),
                                      ),
                                    ],
                                  ) : Row(
                                    children: [
                                      Image.asset(
                                        "registrarse.png",
                                        width: 32.0,
                                      ),
                                      const SizedBox(width: 8.0),
                                      Text(
                                        _esperando ? "Registrando..." : "Registrarse",
                                        style: const TextStyle(
                                          fontFamily: "Helvetica Neue Black Cond",
                                          fontSize: 28.0,
                                          color: Colors.white,
                                        ),
                                      ),
                                    ],
                                  ),
                                  disabledColor: Colors.grey,
                                  onPressed: _esperando ? null : !_tieneCuenta ? () async {
                                    FocusScope.of(context).requestFocus(FocusNode());
                                    _errores["nombre"] = _nombreController.text.isEmpty;
                                    _errores["ciudad"] = _ciudadController.text.isEmpty;
                                    _errores["estado"] = _estadoController.text.isEmpty;
                                    _errores["numTel"] = _numTelController.text.isEmpty;
                                    _errores["correo"] = _correoController.text.isEmpty;
                                    _errores["contra"] = _contraController.text.isEmpty;
                                    _errores["confContra"] = _confContraController.text.isEmpty;

                                    bool hasError = false;
                                    bool paisEstadoEmpty = false;

                                    _errores.forEach((key, value) {
                                      hasError = value;
                                    });

                                    if(!_tieneEstados){
                                      _estado = _estadoController.text;
                                    }

                                    if(!_tieneCiudades){
                                      _municipio = _ciudadController.text;
                                    }

                                    if(hasError){
                                      setState(() {});
                                      return;
                                    }

                                    if(_pais.isEmpty){
                                      Fluttertoast.showToast(
                                        msg: "Antes de avanzar debes seleccionar un país.",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                      paisEstadoEmpty = true;
                                    }

                                    if(_estado.isEmpty){
                                      Fluttertoast.showToast(
                                        msg: "Antes de avanzar debes seleccionar un estado.",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                      paisEstadoEmpty = true;
                                    }

                                    if(paisEstadoEmpty){
                                      setState(() {});
                                      return;
                                    }

                                    final contra = _contraController.text;
                                    final contraComp = _confContraController.text;

                                    _confContraController.clear();

                                    _contrasIguales = contra == contraComp;

                                    if(!_contrasIguales){
                                      Fluttertoast.showToast(
                                        msg: "Las contraseñas no coinciden.",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                      setState(() {});
                                      return;
                                    }

                                    _esperando = true;
                                    setState(() {});

                                    final paisArr = _pais.split(" - ");
                                    final paisStr = paisArr.last;

                                    final registrado = await registrarInfo(
                                      _nombreController.text,
                                      paisStr,
                                      _estado,
                                      _municipio,
                                      _numTelController.text,
                                      _correoController.text,
                                      _contraController.text,
                                    );

                                    _esperando = false;
                                    setState(() {});
                                    if(registrado){
                                      model.updateNombreCompleto(_nombreController.text);
                                      model.updatePais(_pais);
                                      model.updateEstado(_estado);
                                      model.updateCiudad(_municipio);
                                      model.updateNumTel(_numTelController.text);
                                      model.updateCorreo(_correoController.text);
                                      model.updateIDUsuario(_idUsuario);
                                      model.updateAccessToken(_accessToken);
                                      Navigator.push(context, MaterialPageRoute(
                                        builder: (context) => VerificacionPage(
                                          correo: _correoController.text,
                                          numTel: _numTelController.text,
                                          pais: _pais,
                                          verificacion: "1",
                                          idUsuario: _idUsuario,
                                        ),
                                      ));
                                    }else{
                                      Fluttertoast.showToast(
                                        msg: "Hubo un error al registrar su información. Por favor contacte al departamento de TI de S&P México.",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }
                                  } : (){
                                    bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(_correoController.text);
                                    if(_correoController.text.isEmpty){
                                      Fluttertoast.showToast(
                                        msg: "Por favor ingrese un correo electrónico",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }else if(_contraController.text.isEmpty){
                                      Fluttertoast.showToast(
                                        msg: "Por favor ingrese su contraseña",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }else if(!emailValid){
                                      Fluttertoast.showToast(
                                        msg: "El correo ingresado no tiene un formato válido",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }else if(_contraController.text.length < 8){
                                      Fluttertoast.showToast(
                                        msg: "La contraseña debe tener al menos 8 caracteres",
                                        toastLength: Toast.LENGTH_SHORT,
                                        timeInSecForIosWeb: 4,
                                        gravity: ToastGravity.CENTER,
                                        webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                      );
                                    }else{
                                      setState(() => _esperando = true);
                                      _loginVentilacionProvider.fetchLogin(_correoController.text, _contraController.text).then((loginModel){
                                        if(!loginModel.response){
                                          Fluttertoast.showToast(
                                            msg: loginModel.message,
                                            toastLength: Toast.LENGTH_SHORT,
                                            timeInSecForIosWeb: 4,
                                            gravity: ToastGravity.CENTER,
                                            webBgColor: "linear-gradient(to right, #b40404, #ff0000)",
                                          );
                                          setState(() => _esperando = false);
                                        }else{
                                          model.updateNombreCompleto(loginModel.result.nombre);
                                          model.updatePais(loginModel.result.pais);
                                          model.updateEstado(loginModel.result.estado);
                                          model.updateCiudad(loginModel.result.ciudad);
                                          model.updateNumTel(loginModel.result.movil);
                                          model.updateCorreo(loginModel.result.correo);
                                          model.updateIDUsuario(loginModel.result.idUsuario);
                                          model.updateAccessToken(loginModel.result.accessToken);

                                          final correo = _correoController.text;

                                          _correoController.clear();
                                          _contraController.clear();
                                          setState(() => _esperando = false);

                                          if(loginModel.result.verificacion == "1" || loginModel.result.verificacion == "2" || loginModel.result.verificacion == "3"){
                                            Navigator.push(context, MaterialPageRoute(
                                              builder: (context) => VerificacionPage(
                                                correo: correo,
                                                numTel: loginModel.result.movil,
                                                pais: loginModel.result.pais,
                                                verificacion: loginModel.result.verificacion,
                                                idUsuario: loginModel.result.idUsuario,
                                              ),
                                            ));
                                          }else{
                                            Navigator.pushNamed(context, "index");
                                          }
                                        }
                                      });
                                    }
                                  }
                              )
                            ],
                          ),
                        ),
                        const SizedBox(
                          height: 32.0,
                        ),
                      ],
                    ),
                  ),
                ),
              );
            },
          ),
        );
      },
    );
  }
}
