mirrored_repositories/GoSocio/lib
import 'dart:io';
import 'package:GoSocio/models/user.dart';
import 'package:GoSocio/pages/activity_feed.dart';
import 'package:GoSocio/pages/create_account.dart';
import 'package:GoSocio/pages/profile.dart';
import 'package:GoSocio/pages/search.dart';
import 'package:GoSocio/pages/timeline.dart';
import 'package:GoSocio/pages/upload.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:firebase_messaging/firebase_messaging.dart';


final GoogleSignIn googleSignIn = GoogleSignIn();
final StorageReference storageRef = FirebaseStorage.instance.ref();
final usersRef = FirebaseFirestore.instance.collection('users');
final postsRef = FirebaseFirestore.instance.collection('posts');
final commentsRef = FirebaseFirestore.instance.collection('comments');
final activityFeedRef = FirebaseFirestore.instance.collection('feed');
final followersRef = FirebaseFirestore.instance.collection('followers');
final followingRef = FirebaseFirestore.instance.collection('following');
final timelineRef = FirebaseFirestore.instance.collection('timeline');
final DateTime timestamp = DateTime.now();
User currentUser;

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  bool isAuth = false;
  PageController pageController;
  int pageIndex =0;

  @override
  void initState(){
    super.initState();
    pageController = PageController();
    // DEtects when user signed in 
    googleSignIn.onCurrentUserChanged.listen((account) {
        handleSignIn(account);
      }, onError: (err){
          print('Error signing in : $err');
     });
     //Reauthenticate user when app is opened
     googleSignIn.signInSilently(suppressErrors: false)
     .then((account) => {
       handleSignIn(account),
     }).catchError((err){
       print('Error signing in : $err');
     });
  }

  handleSignIn(GoogleSignInAccount account) async{
     if(account != null){
        await createUserInFireStore();
        setState(() {
          isAuth = true;
        });
        configurePushNotifications();
      }else{
        setState(() {
          isAuth = false;
        });
      }
  }

  configurePushNotifications(){
    final GoogleSignInAccount user = googleSignIn.currentUser;
    if(Platform.isIOS) getiOSPermission();

    _firebaseMessaging.getToken().then((token) {
      print("Firebase Messaging Token: $token\n");
      usersRef
      .doc(user.id)
      .update({"androidNotificationToken": token});
    });

    _firebaseMessaging.configure(
      // onLaunch: (Map<String, dynamic> message) async{},
      // onResume:  (Map<String, dynamic> message) async{},
      onMessage:  (Map<String, dynamic> message) async{
        print("on message: $message\n");
        final String recipientId = message['data']['recipient'];
        final String body = message['notification']['body'];
        if(recipientId == user.id){
          print("Notification shown!");
          SnackBar snackbar = SnackBar(content: Text(
            body, overflow: TextOverflow.ellipsis,));
            _scaffoldKey.currentState.showSnackBar(snackbar);
        }
        print("Notification Not Shown");
      },
    );
  }

  getiOSPermission(){
    _firebaseMessaging.requestNotificationPermissions
    (IosNotificationSettings(alert: true, badge: true, sound: true));
    _firebaseMessaging.onIosSettingsRegistered.listen((settings) {
      print("Settings registered: $settings");
     });
  }

  createUserInFireStore() async{
    // 1. check if user exists in users collection in database (according to their id)
    final GoogleSignInAccount user = googleSignIn.currentUser;
    DocumentSnapshot doc = await usersRef.doc(user.id).get();

    if(!doc.exists){
      // 2. if the user doesn't exist we are gonna take the use to the create account page
      final username = await Navigator.push(context, MaterialPageRoute(builder: (context) 
      => CreateAccount()));

      // 3. get username from create account , use it to make new user document in users collection
        usersRef.doc(user.id).set({
          "id":user.id,
          "username":username,
          "photoUrl": user.photoUrl,
          "email": user.email,
          "displayName": user.displayName,
          "bio": "",
          "timestamp": timestamp,
        });
        //make new user their own follower (to include their posts in their timeline)
        await followersRef
        .doc(user.id)
        .collection('userFollowers')
        .doc(user.id)
        .set({});

        doc = await usersRef.doc(user.id).get();
    }
    currentUser = User.fromDocument(doc);
    print(currentUser);
    print(currentUser.username);
  }

  @override
  void dispose(){
    pageController.dispose();
    super.dispose();
  }

  login() async{
    await googleSignIn.signIn();
  }

  logout() async{
    await googleSignIn.signOut();
  }

  onPageChanged(int pageIndex){
    setState(() {
      this.pageIndex = pageIndex;
    });
  }

  onTap(int pageIndex){
      pageController.animateToPage(
        pageIndex,
        duration:Duration(milliseconds: 300) ,
        curve: Curves.easeInOut,
        );
  }

  Scaffold buildAuthScreen(){
    // return RaisedButton(
    //   child: Text('Logout'),
    //   onPressed: logout,
    // );
    return Scaffold(
      key: _scaffoldKey,
      body: PageView(
        children: <Widget>[
        Timeline(currentUser : currentUser),
        ActivityFeed(),
        Upload(currentUser : currentUser),
        Search(),
        Profile(profileId: currentUser?.id),
      ],
      controller: pageController,
      onPageChanged: onPageChanged,
      physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
        currentIndex: pageIndex,
        onTap: onTap,
        activeColor: Theme.of(context).primaryColor,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.whatshot)),
          BottomNavigationBarItem(icon: Icon(Icons.notifications_active)),
          BottomNavigationBarItem(icon: Icon(Icons.photo_camera, size: 35.0,)),
          BottomNavigationBarItem(icon: Icon(Icons.search)),
          BottomNavigationBarItem(icon: Icon(Icons.account_circle)),
        ],
      ),
    );
  }

  Scaffold buildUnAuthScreen(){
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topRight,
            end: Alignment.bottomLeft,
            colors: [
              Theme.of(context).accentColor,
              Theme.of(context).primaryColor,
            ]
          ),
        ),
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children:<Widget>[
            Text('GoSocio',
            style: TextStyle(
              fontSize: 90.0,
              color: Colors.white,
              fontFamily: "Signatra",
            ),
            ),
            GestureDetector(
              onTap:() => login(),
              child: Container(
                width: 260.0,
                height: 60.0,
                decoration : BoxDecoration(
                  image: DecorationImage(
                    image: AssetImage('assets/images/google_signin_button.png'),
                    fit:BoxFit.cover,
                    ),
                ),
              ),
            ),
          ]
        ),
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return isAuth ? buildAuthScreen() : buildUnAuthScreen();
  }
}
