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

import 'package:connectivity/connectivity.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:quiosco_soler/src/main_model.dart';
import 'package:scoped_model/scoped_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Map _source = {ConnectivityResult.none: false};
  MyConnectivity _connectivity = MyConnectivity.instance;
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  @override
  void initState() {
    super.initState();
    _initializeDownloader();
    _connectivity.initialize();
    _connectivity.myStream.listen((source) {
      _source = source;

      if(_source.keys.toList()[0] == ConnectivityResult.none){
        _navigatorKey.currentState!.pushReplacementNamed("nocon");
      }else{
        _navigatorKey.currentState!.pushReplacementNamed("tmp");
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
    _connectivity.disposeStream();
  }

  Future<void> _initializeDownloader() async{
    WidgetsFlutterBinding.ensureInitialized();
    try{
      await FlutterDownloader.initialize(debug: true);
    }catch(_){
      Fluttertoast.showToast(msg: "Error al iniciar el servicio de descargas");
    }
  }
  
  @override
  Widget build(BuildContext context) {
    final MainModel _model = MainModel();

    return ScopedModel<MainModel>(
      model: _model,
      child: MaterialApp(
        navigatorKey: _navigatorKey,
        title: "Quiosco",
        debugShowCheckedModeBanner: false,
        initialRoute: "tmp",
        routes: {
          'index'  : (BuildContext context) => Index(),
          'menini' : (BuildContext context) => MenuInicio(),
          'apl'    : (BuildContext context) => APL(),
          'ener'   : (BuildContext context) => RecuperacionEnergia(),
          'home'   : (BuildContext context) => HomePage(),
          'secc'   : (BuildContext context) => SectionsPage(),
          'cate'   : (BuildContext context) => CategoriesPage(),
          'files'  : (BuildContext context) => FilesPage(),
          'search' : (BuildContext context) => SearchPage(),
          'order'  : (BuildContext context) => OrderPage(),
          'about'  : (BuildContext context) => AboutPage(),
          'check'  : (BuildContext context) => CheckPage(),
          'sinsec' : (BuildContext context) => SingleSectionsPage(),
          'sincat' : (BuildContext context) => SingleCategoriesPage(),
          'memform': (BuildContext context) => FormularioPage(),
          'memind' : (BuildContext context) => IndexMemoriasPage(),
          'nocon'  : (BuildContext context) => NoConnections(),
          'tmp'    : (BuildContext context) => CalculadoraAmbientalPage()
        },
        onGenerateRoute: (RouteSettings settings){
          return MaterialPageRoute(
            builder: (BuildContext context) => CheckPage(),
          );
        },
        theme: ThemeData(
          brightness: Brightness.light,
          primaryColor: const Color.fromRGBO(255, 0, 0, 1),
          splashColor: const Color.fromRGBO(180, 4, 4, 1),
          colorScheme: const ColorScheme.light(
            primary: Color.fromRGBO(180, 4, 4, 2),
          ).copyWith(
            secondary: const Color.fromRGBO(180, 4, 4, 1),
          ),
        ),
        localizationsDelegates: const [
          GlobalMaterialLocalizations.delegate
        ],
        supportedLocales: const [
          Locale("en"),
          Locale("es"),
        ],
      ),
    );
  }
}

class MyConnectivity{
  MyConnectivity._internal();
  
  static final MyConnectivity _instance = MyConnectivity._internal();
  static MyConnectivity get instance => _instance;
  Connectivity connectivity = Connectivity();
  StreamController controller = StreamController.broadcast();
  Stream get myStream => controller.stream;
  
  void initialize() async{
    ConnectivityResult result = await connectivity.checkConnectivity();
    _checkStatus(result);
    
    connectivity.onConnectivityChanged.listen((result) { 
      _checkStatus(result);
    });
  }
  
  void _checkStatus(ConnectivityResult result) async{
    bool isOnline = false;
    try{
      final result = await InternetAddress.lookup("https://smart.solerpalau.mx/PR/");
      if(result.isNotEmpty && result[0].rawAddress.isNotEmpty){
        isOnline = true;
      }else{
        isOnline = false;
      }
    }on SocketException catch(_){
      isOnline = false;
    }
    controller.sink.add({result: isOnline});
  }

  void disposeStream() => controller.close();
}

