import 'dart:math';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:localstore/localstore.dart';
import 'package:quiosco_soler_2/memorias_calculo/widgets/cargando.dart';
import 'package:quiosco_soler_2/quiosco/models/permisos_model.dart';
import 'package:quiosco_soler_2/src/providers/db_provider.dart';

import '../../src/providers/login_provider.dart';
import '../models/db_archivos_model.dart';
import '../models/db_categoria_model.dart';
import '../models/db_estante_model.dart';
import '../models/db_secciones_model.dart';
import '../models/response_model.dart';
import '../providers/archivos_provider.dart';
import '../providers/categorias_provider.dart';
import '../providers/estantes_provider.dart';
import '../providers/permisos_provider.dart';
import '../providers/secciones_provider.dart';
import '../providers/valid_token_provider.dart';

class LoginPage extends StatefulWidget {
  final Response response;
  final DateTime dateTime;
  final String pass;

  const LoginPage({
    Key? key,
    required this.response,
    required this.dateTime,
    required this.pass
  }) : super(key: key);

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _dinumController = TextEditingController();
  final _dipassController = TextEditingController();
  final _loginProvider = LoginProvider();
  final _estantesProvider = EstantesProvider();
  final _seccionesProvider = SeccionesProvider();
  final _categoriasProvider = CategoriasProvider();
  final _archivosProvider = ArchivosProvider();
  final _permisosProvider = PermisosProvider();
  final _validTokenProvider = ValidTokenProvider();
  final db = Localstore.instance;
  bool _isLoading = true;
  bool _initializing = false;

  late DateTime _dateTime;
  late Response _response;

  @override
  void dispose() {
    _dinumController.dispose();
    _dipassController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _dateTime = widget.dateTime;
    _response = widget.response;

    if(_response.response!){
      _navigate();
    }else{
      Fluttertoast.showToast(
        msg: widget.response.message!,
        toastLength: Toast.LENGTH_LONG,
        timeInSecForIosWeb: 3,
        gravity: ToastGravity.CENTER,
      );
      _isLoading = false;
    }
  }

  void _navigate() async{
    final valid = await _validTokenProvider.fetchValidToken(_response.result!.accessToken!);
    if(valid){
      final action = await Navigator.pushNamed(context, 'home');
      print(action);
    }else{
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final _screenSize = MediaQuery.of(context).size;
    return Scaffold(
      body: SafeArea(
        child: _isLoading ? const Center(
          child: CircularProgressIndicator(),
        ) : _initializing ? Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            SizedBox(width: _screenSize.width),
            const CircularProgressIndicator(),
            const SizedBox(height: 16),
            const Cargando(text: "Inicializando información")
          ],
        ) : SingleChildScrollView(
          child: Column(
            children: [
              const SizedBox(height: 32.0),
              Row(
                children: const [
                  SizedBox(
                    width: 32.0,
                  ),
                  Image(
                    image: AssetImage('assets/logo.png'),
                    width: 64.0,
                  ),
                  SizedBox(width: 16.0),
                  Expanded(
                    child: Image(
                      image: AssetImage('assets/logo_completo.png'),
                    ),
                  ),
                  SizedBox(width: 32.0)
                ],
              ),
              const SizedBox(height: 48.0),
              const Image(
                image: AssetImage('assets/quiosco.png'),
                width: 88.0,
                fit: BoxFit.cover,
              ),
              const SizedBox(height: 16.0),
              const Text(
                'QUIOSCO',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontFamily: 'Helvetica Neue Black Cond',
                    fontSize: 28.0
                ),
              ),
              const SizedBox(height: 8.0),
              const Text(
                'Colaborador',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontFamily: 'Helvetica Neue Light',
                    fontSize: 22.0,
                    fontWeight: FontWeight.w600,
                    color: Color.fromRGBO(104, 104, 104, 1)
                ),
              ),
              const SizedBox(height: 32.0),
              Container(
                margin: const EdgeInsets.symmetric(horizontal: 32.0),
                child: Column(
                  children: [
                    TextField(
                      autofocus: true,
                      controller: _dinumController,
                      decoration: const InputDecoration(
                        hintText: 'Usuario:',
                        contentPadding: EdgeInsets.zero,
                      ),
                      maxLines: 1,
                      cursorColor: Color.fromRGBO(180, 4, 4, 1),
                      style: const TextStyle(
                          fontSize: 20.0
                      ),
                    ),
                    const SizedBox(height: 16.0),
                    TextField(
                      controller: _dipassController,
                      obscureText: true,
                      decoration: const InputDecoration(
                        hintText: 'Contraseña:',
                        contentPadding: EdgeInsets.zero,
                      ),
                      maxLines: 1,
                      cursorColor: const Color.fromRGBO(180, 4, 4, 1),
                      style: const TextStyle(
                          fontSize: 20.0
                      ),
                    ),
                    const SizedBox(height: 32.0),
                    MaterialButton(
                      elevation: 4.0,
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      minWidth: _screenSize.width-64.0,
                      color: const Color.fromRGBO(255, 0, 0, 1),
                      child: const Text(
                        'Entrar',
                        style: TextStyle(
                            fontFamily: 'Helvetica Neue Black Cond',
                            fontSize: 28.0,
                            color: Colors.white
                        ),
                      ),
                      onPressed: () async{
                        FocusScope.of(context).requestFocus(FocusNode());
                        Fluttertoast.showToast(
                          msg: 'Validando datos...',
                          toastLength: Toast.LENGTH_SHORT,
                          gravity: ToastGravity.CENTER,
                          timeInSecForIosWeb: 1,
                        );

                        final Response login = await _loginProvider.fetchLogin(_dinumController.text, _dipassController.text);

                        if(!login.response!){
                          Fluttertoast.showToast(
                            msg: 'Credenciales inválidas, revisa tus datos por favor',
                            toastLength: Toast.LENGTH_SHORT,
                            gravity: ToastGravity.CENTER,
                            timeInSecForIosWeb: 1,
                          );
                          _dinumController.text = "";
                          _dipassController.text = "";
                        }else{
                          setState(() => _initializing = true);
                          await DBProvider.db.deleteAllLogs();
                          DBProvider.db.insertLoginInfo(login, DateTime.now(), _dipassController.text);

                          final permisos = await _permisosProvider.fetchPermisos(login.result!.dinum!, login.result!.accessToken!);
                          for(int i = 0; i < permisos.result!.length; i++){
                            if(permisos.result![i].tipo == Tipo.ESTA){
                              final estante = await _estantesProvider.fetchEstante(login.result!.accessToken!, permisos.result![i].ides!);
                              final dbEstante = DbEstantes(
                                ides: int.parse(estante.result!.ides!),
                                esta: estante.result!.esta,
                                acti: estante.result!.acti,
                                idim: estante.result!.idim,
                                uscr: int.parse(estante.result!.uscr!),
                                fecr: estante.result!.fecr,
                                usmo: estante.result!.usmo == null ? 0 : int.parse(estante.result!.usmo),
                                femo: estante.result!.femo ?? DateTime.fromMicrosecondsSinceEpoch(0).toIso8601String(),
                                orde: int.parse(estante.result!.orde!),
                              );
                              DBProvider.db.newEstanteRaw(dbEstante);
                            }else if(permisos.result![i].tipo == Tipo.SECC){
                              final seccion = await _seccionesProvider.fetchSecciones(login.result!.accessToken!, permisos.result![i].idse!);
                              final dbSeccion = DbSecciones(
                                idse: int.parse(seccion.result!.idse!),
                                esta: "",
                                ides: int.parse(seccion.result!.ides!),
                                secc: seccion.result!.secc,
                                acti: seccion.result!.acti,
                                idim: seccion.result!.idim,
                                uscr: int.parse(seccion.result!.uscr!),
                                fecr: seccion.result!.fecr,
                                usmo: seccion.result!.usmo == null ? 0 : int.parse(seccion.result!.usmo),
                                femo: seccion.result!.femo ?? DateTime.fromMicrosecondsSinceEpoch(0).toIso8601String(),
                                orde: int.parse(seccion.result!.orde!),
                              );
                              DBProvider.db.newSeccionRaw(dbSeccion);
                            }else if(permisos.result![i].tipo == Tipo.CATE){
                              final categoria = await _categoriasProvider.fetchCategoria(login.result!.accessToken!, permisos.result![i].idca!);
                              final dbCategoria = DbCategorias(
                                  idca: int.parse(categoria!.result!.idca!),
                                  secc: "",
                                  esta: "",
                                  idse: int.parse(categoria.result!.idse!),
                                  cate: categoria.result!.cate,
                                  acti: categoria.result!.acti,
                                  idim: categoria.result!.idim,
                                  uscr: int.parse(categoria.result!.uscr!),
                                  fecr: categoria.result!.fecr,
                                  usmo: categoria.result!.usmo == null ? 0 : int.parse(categoria.result!.usmo),
                                  femo: categoria.result!.femo ?? DateTime.fromMicrosecondsSinceEpoch(0).toIso8601String(),
                                  orde: int.parse(categoria.result!.orde!)
                              );
                              DBProvider.db.newCategoriaRaw(dbCategoria);
                            }
                          }

                          final archivos = await _archivosProvider.fetchArchivos(login.result!.accessToken!, login.result!.dinum!);
                          for(int i = 0; i < archivos.result!.length; i++){
                            final dbArchivo = DbArchivos(
                                idar: int.parse(archivos.result![i].idar!),
                                esta: archivos.result![i].esta,
                                secc: archivos.result![i].secc,
                                cate: archivos.result![i].cate,
                                ides: int.parse(archivos.result![i].ides!),
                                idse: int.parse(archivos.result![i].idse!),
                                idca: int.parse(archivos.result![i].idca!),
                                arch: archivos.result![i].arch,
                                acti: archivos.result![i].acti,
                                arfi: archivos.result![i].arfi,
                                idim: archivos.result![i].idim,
                                uscr: int.parse(archivos.result![i].uscr!),
                                fecr: archivos.result![i].fecr,
                                usel: int.parse(archivos.result![i].usel!),
                                feel: archivos.result![i].feel,
                                orde: int.parse(archivos.result![i].orde!),
                                femo: archivos.result![i].femo,
                                usmo: int.parse(archivos.result![i].usmo!),
                                dinombre: archivos.result![i].dinombre
                            );
                            DBProvider.db.newArchivosRaw(dbArchivo);
                          }

                          final id = db.collection('quiosco').doc().id;
                          db.collection('quiosco').doc(id).set({
                            'user' : login.result!.user,
                            'accessToken': login.result!.accessToken,
                            'dinum': login.result!.dinum,
                          });

                          setState(() => _initializing = false);
                          Fluttertoast.showToast(
                            msg: 'Inicio de sesión correcto',
                            toastLength: Toast.LENGTH_SHORT,
                            gravity: ToastGravity.CENTER,
                            timeInSecForIosWeb: 2,
                          );

                          dynamic action = '';
                          if(login.result!.lsec == 'Si'){
                            action = await Navigator.pushNamed(context, 'home');
                          }else{
                            action = await Navigator.pushNamed(context, 'otp');
                          }
                        }
                      },
                    ),
                    const SizedBox(height: 16.0),
                    MaterialButton(
                      elevation: 4.0,
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      minWidth: _screenSize.width-64.0,
                      color: const Color.fromRGBO(255, 0, 0, 1),
                      child: const Text(
                        'Regresar',
                        style: TextStyle(
                          fontFamily: 'Helvetica Neue Black Cond',
                          fontSize: 28.0,
                          color: Colors.white,
                        ),
                      ),
                      onPressed: () => Navigator.pop(context),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
